INASOFT 管理人のひとこと


フリーソフトダウンロードサイト「INASOFT」の管理人 矢吹拓也 が日々の「ひとこと」を語るページです。
2021年1月1日より、旧ブログ(blog.inasoft.org)からお引越ししました。
・INASOFT Webサイト: https://www.inasoft.org/
・管理人のふたこと(長文記事/寄稿文): https://www.inasoft.org/talk/
2022年7月下旬より再び本業多忙化してきているため、更新頻度は落ちます。 [2022/7/24 19:32]

目次 | ←前へ / 2016-01-15 00:00 / 次へ→ / 最新へ⇒

■Visual C++で2GB超のファイルを取り扱う方法

2016年 1月15日(金) 0:00:00 [さくらのブログから転記]



RSSRSS配信中
https://www.inasoft.org/



先日、仕事で作っていた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() を使うようにして置いた方が良さそうですね。




目次 | ←前へ / 2016-01-15 00:00 / 次へ→ / 最新へ⇒


目次の表示:


ブログではないので、コメント機能とトラックバック機能は提供していません。ご質問・ご意見等はメールフィードバックまたはTwitter等からお願いします。いただいたご質問・ご意見などは、この「管理人のひとこと」の記事に追加、あるいは新規の記事にする形で一部または全文をそのまま、あるいは加工させていただいた上で、ご紹介させていただく場合があります。
当サイトでは掲載内容による不具合等に関する責任を持ちません。また、内容の正確性についての保証もありませんので、情報をご利用の際は、利用者の自己責任で確認をお願いします。本ページは公開から1年半後の任意のタイミングで削除される予定です。


- 最近の更新 -



3212513 (+0210)[+0214]

Copyright© 2010-2024 INASOFT