使用C用第二个替换文件的前半部分并截断?

所以我有一个大文件,一旦达到一定的大小,我想完全删除前半部分并将下半部分向下移动,有效地使其减小一半。 Heres是我在想的:

FILE *fp, *start; int ch, block_length, filesize; char c; //open the file and initialize pointers fp = fopen(FILEPATH, "rb+"); start = fp; rewind(start); //Check the size of the file fseek(fp, 0, SEEK_END); filesize = ftell(fp); if(filesize >= LOG_MAX_FILE_SIZE) { //Go to middle of file fseek(fp, (-1) * LOG_MAX_FILE_SIZE/2, SEEK_END); //Go forwards until you get a new line character to avoid cutting a line in half for(;;) { //Read char fread(&ch, 1, 1, fp); //Advance pointer fseek(fp, 1, SEEK_CUR); if( (char)ch == '\n' || ch == EOF) break; } //fp is now after newline char roughly in middle of file //Loop over bytes and put them at start of file until EOF for(;;) { //Read char fread(&ch, 1, 1, fp); //Advance pointer fseek(fp, 1, SEEK_CUR); if(ch != EOF) { c = (char)ch; fwrite(&c,1,1,start); fflush(start); //Advance start fseek(start, 1, SEEK_CUR); } else break; } //Calculate length of this new file block_length = ftell(start); //Go back to start rewind(start); //Truncate file to block length ftruncate(fileno(start), block_length); } 

但是,这似乎做了一些非常奇怪的事情(用’f’填充文件,混合行和其中的一些字符等)。 有没有人对我在这段代码中做错了什么有任何想法? 先谢谢!

我认为部分问题是你在阅读时使用fseek 。 对fread和fwrite的调用使文件指针前进。 如果你打电话给fseek,它会跳过下一个字符。

在以下代码序列中, fread调用将读取一个字符并将当前偏移量提前到下一个字符。 然后随后的fseek跳过该角色并移动到下一个角色。 所以它会读取每一个字符。

 fread(&ch, 1, 1, fp); fseek(fp, 1, SEEK_CUR); 

写调用存在同样的问题(它不需要后续搜索)。 此外,由于对OP的编辑显示start和fp是相同的值,逻辑将不正确(您需要单独的文件指针来使用该逻辑)。

找到你的起始位置后,你可以将文件复制成大块(一次说64 KB),从尾部读取然后跳到开始和写入,然后跳回尾部…

ftruncate()是释放空间的最后一步。

考虑是否更容易使读取文件流和写入文件流指向同一文件。 减少对单个流的搜索(如此简单的代码)。 这是我可能会做的。