|
![]() ![]() ![]() ![]() ![]() | |
先日、仕事で作っていたWindows向けのツールで、3GBのファイルを扱う必要が出てきました。 C言語の標準のファイル入出力関数を使っていたプログラムだったのですが、どんだけ多くの改修を加えなければならないのかとビクビクしていたのですが、よくよく調べてみると、それほど難しくなかったみたいです。 というのも、ただ単にファイルを開いて、ファイルを入出力して、ファイルを閉じるくらいであれば、これまで通り fopen(), fgets(), fread(), fputs(), fwrite(), fclose() などの関数を使っておけばよいみたいで。 どんなときに注意が必要かというと、ユーザープログラム側とファイルポインタの現在位置情報のやりとりが生じるようなとき。 例えば、fseek() や ftell() を使う場合ですね。 fseek() は、ファイルポインタの現在位置を任意の位置に移動します。ところが、fseek()の引数はlong型です。Windowsのlongは、32bit CPUであっても64bit CPUであっても、32bit整数型ですので、ファイルポインタは 0~231-1 の範囲でしか移動できません。 231-1 を超える位置にファイルポインタを移動させたければ、_fseeki64()を使うことになりなります。 ftell() は、ファイルポインタの現在位置を返す関数です。ところが、ftell()の戻り値はlong型です。 2GB超のファイルポインタの位置を取得したい場合は、_ftelli64()を使うことになります。 先のツールでは、ファイルサイズを得るために、 【2/17追記】【注意】下のような方法でファイルサイズを求めることを奨励しているサイトは多いのですが、fseek()でファイル終端位置にシークする操作は結果が保証されないことにされており、このようなコードを記述してはいけないそうです。fstat()を使うのが正しいやり方とのこと。 fseek(fp, 0, SEEK_END); long fsize = ftell(fp); fseek(fp, 0, SEEK_SET); というようなことをやっておりましたので、この部分を 【2/17追記】【注意】下のような方法でファイルサイズを求めることを奨励しているサイトは多いのですが、fseek()でファイル終端位置にシークする操作は結果が保証されないことにされており、このようなコードを記述してはいけないそうです。 _fseeki64(fp, 0, SEEK_END); __int64 fsize = _ftelli64(fp); _fseeki64(fp, 0, SEEK_SET); に書き換えました。 ついでに、fsizeを表示するために printf("%ld", fsize); としていた箇所は、printf("%I64d", fsize); に差し替えです。 ちなみに、2GB以下のファイルに対しても、_fseeki64() や _ftelli64() は使用可能ですので、他の処理系への移植予定がなく、将来的に2GB超のファイルを扱う可能性があるならば、最初から _fseeki64() や _ftelli64() を使うようにして置いた方が良さそうですね。 目次の表示: ブログではないので、コメント機能とトラックバック機能は提供していません。ご質問・ご意見等はメール、フィードバックまたはTwitter等からお願いします。いただいたご質問・ご意見などは、この「管理人のひとこと」の記事に追加、あるいは新規の記事にする形で一部または全文をそのまま、あるいは加工させていただいた上で、ご紹介させていただく場合があります。 当サイトでは掲載内容による不具合等に関する責任を持ちません。また、内容の正確性についての保証もありませんので、情報をご利用の際は、利用者の自己責任で確認をお願いします。 |
- 最近の更新 - |
|
3279656 (+0405)[+0505] Copyright© 2010-2025 INASOFT |