C で 24 GB の XML ファイルを読み込もうとしていますが、うまくいきません。読み込んだときに ftell() を使用して現在の位置を出力していますが、十分に大きな数値になると、小さな数値に戻って最初からやり直し、ファイル全体で 20% を取得することさえありません。これは、位置 (long) を格納するために使用される変数の範囲に問題があると思います。http://msdn.microsoft.com/en-us/library/s3f49ktz( VS .80).aspx、私のファイルのサイズは 25,000,000,000 バイトです。long long は機能するはずですが、コンパイラ ( Cygwin / mingw32 ) が使用するものを変更したり、fopen64 を使用するにはどうすればよいですか?
6 に答える
OS 提供のファイル関数CreateFile および ReadFileを使用してみてください。ファイル ポインターのトピックによると、位置は 64 ビット値として格納されます。
このftell()
関数は通常、32 ビット システムunsigned long
では最大 2 32バイト (4 GB) の を返します。そのため、24 GB ファイルのファイル オフセットを 32 ビット に収めることはできませんlong
。
ftell64()
関数を使用できるか、標準fgetpos()
関数がより大きなオフセットを返す場合があります。
Loadmaster が提案する 64 ビット方式を使用できない場合は、ファイルを分割する必要があると思います。
このリソースは、_telli64() を使用して可能であることを示唆しているようです。私はmingwを使用していないので、これをテストすることはできません。
私は答えを見つけました。fopen、fseek、fread、fwrite を使用する代わりに、_open、lseeki64、read、write を使用しています。また、4 GB を超えるファイルに書き込みとシークを行うことができます。
編集: 後者の関数は前者よりも約 6 倍遅いようです。それを説明できる人に賞金をあげます。
編集:ああ、ここで read() と友達がバッファリングされていないことを学びました。 read() と fread() の違いは何ですか?
1つのファイルでこれを行う方法はわかりませんが、少しハックですが、ファイルを適切に分割することが実際のオプションではない場合は、ファイルを一時的に分割する関数をいくつか書くことができます。 () ファイルを移動し、分割ポイントに到達すると ftell() を新しいファイルにスワップし、終了する前にファイルをつなぎ合わせる別のファイルにスワップします。完全に失敗したアプローチですが、より良い解決策が明らかにならない場合、それは仕事を成し遂げる方法になる可能性があります.
Microsoft Cライブラリのftell()が32ビット値を返し、2 GBに達すると明らかに偽の値を返す場合でも、ファイルを読み取るだけで問題なく動作するはずです。それとも、ファイル内を探す必要がありますか?そのためには、_ftelli64()と_fseeki64()が必要です。
一部のUnixシステムとは異なり、ファイルを開くときに「64ビットモード」であることを示す特別なフラグは必要ありません。基盤となるWin32APIは、大きなファイルを適切に処理します。