2

大きなファイルがあり、一定のサイズになったら、前半を完全に削除して後半をシフトダウンし、実質的に半分のサイズにします。これが私が考えていることです:

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」を埋め込んだり、行とその中のいくつかの文字を混同したりするなど)。このコードで私が間違っている可能性があることについて誰かが何か考えを持っていますか?よろしくお願いします!

4

2 に答える 2

1

fseek問題の一部は、読書中に使用していることだと思います。fread と fwrite の呼び出しは、ファイル ポインターを進めます。fseek を呼び出すと、次の文字をスキップします。

次のコード シーケンスでは、fread呼び出しによって文字が読み取られ、現在のオフセットが次の文字に進められます。その後fseek、その文字をスキップして次の文字に移動します。したがって、1 文字おきに読み取ります。

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

書き込み呼び出しにも同じ問題があります (後続のシークは必要ありません)。また、OP の編集では start と fp が同じ値であることを示しているため、ロジックは正しくありません (そのロジックを使用するには別のファイル ポインターが必要になります)。

于 2013-02-15T23:45:59.737 に答える
0

開始位置を見つけたら、ファイルを大きなチャンク (一度に 64 KB など) でコピーし、末尾から読み取り、先頭に向かってスキップして書き込み、最後にスキップして戻ることができます...

ftruncate()スペースを解放する最後のステップです。

読み取りファイル ストリームと書き込みファイル ストリームが同じファイルを指す方が簡単かどうかを検討してください。単一のストリームのシークが少ない (コードが単純になる)。それは私がおそらくすることです。

于 2013-02-15T23:49:09.933 に答える