1

FILE* fileバイナリデータを保持する があります。このデータが double のリストであり、最後のエントリが double とは何かを説明する文字列であるとしましょう。この文字列を変更したい (新しい文字列は短いかもしれない)。まず、古い文字列を削除します。文字列の開始点を見つける必要があります:

fseek(file,-size(sring.size()),SEEK_END);

そして、私は何をすべきですか?[ファイルの終わりの削除]リンクを見つけましたが、どれを使用すればよいかわかりません... ファイルのサイズを変更したら、新しい文字列をfwrite.

4

2 に答える 2

6

どちらFILE*も iostream は切り捨てをサポートしていません。新しいファイルが古いファイルよりも短くなるようにファイルを編集する場合は、2 つの解決策があります。

  • 通常の解決策は、元のファイルを新しいファイルにコピーし、変更を加えることです。終了したら、新しいファイルを閉じ、エラーがないことを確認してから (重要なポイント)、元のファイルを削除し、元の名前を持つように新しいファイルに名前を変更します。元のファイルへのハード リンクが存在する場合、Unix システムで問題が発生する可能性があります。(現在は誰もがソフト リンクを使用しているため、通常、これは問題ではありません。そうである場合はstat、元のファイルを使用し、st_nlinkフィールドが 1 より大きい場合は、新しいファイルを元のファイルにコピーしてから、新しいファイルを削除します。 ) 一方、これは最も一般的なオプションです。ファイル内の任意の場所で、すべてのタイプの変更に対して機能します。

  • 通常、ファイルを切り捨てるためのシステム固有の機能が下位レベルにあります。Unix では、これはftruncate. ただし、最初に切り捨てたいバイト数を見つける必要があります。ftruncate開いているファイルが必要ですが、ファイル内の現在の位置で切り捨てられません。したがって、1) ファイル内のこの最後の行の開始を見つける、2) それをシークする、3) 新しい値を書き込む、4) を呼び出すftell(またはftello、長さが大きすぎて a に収まらない場合long)必要があります。新しい終了位置を見つけます。この時点で FILE*、下位レベルと同期するという問題があります。個人的には、私はファイルを開き、fcloseそれをで再度開き、この開いたファイル記述子で実行します。(実際、個人的には、 , ,を使用してすべての作業を行いますopenftruncateopenreadlseekwriteftruncate およびclose。そしてstat、ファイルの長さを前もって調べることもできます。double を変換する必要がなければ、FILE*追加するものは何もありません。

原則として、私は最初の解決策を採用し、2 番目の解決策が遅すぎることが判明した場合にのみ試します。(たとえば、ファイルに数十億の double が含まれている場合、それらのコピーには時間がかかります。)

于 2013-03-01T09:44:06.400 に答える
4

ファイルのサイズを変更したい場合、ftruncate()( http://www.linuxmanpages.com/man2/ftruncate.2.php ) が探している関数です。ただし、 のファイル記述子を取得するfileno()には、構造体を呼び出す必要があります。FILE *ftruncate()

ファイルのサイズが縮小された後の新しいデータ (新しい文字列) の追加については、最後まで検索して ( fseek(file, 0, SEEK_END))、fwrite()そこに 'ing するだけで済みます。

編集:fflush()ファイルを切り詰める前に呼び出すことを忘れないでください!

于 2013-03-01T09:23:03.627 に答える