fgetpos()
関数を使用することと、関数をfsetpos()
使用してファイル内の位置を取得および設定することの違いは何ですか?ftell()
fseek()
何が良いのですかfgetpos()
?なぜandfsetpos()
の代わりに使用されるのでしょうか?ftell()
fseek()
fgetpos()
関数を使用することと、関数をfsetpos()
使用してファイル内の位置を取得および設定することの違いは何ですか?ftell()
fseek()
何が良いのですかfgetpos()
?なぜandfsetpos()
の代わりに使用されるのでしょうか?ftell()
fseek()
上記の答えはどれも正しくありません。実際、 とfsetpos
同じ意味で使用するとfseek
、セキュリティ上の欠陥が発生する可能性があります ( https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255 )。
その理由は、 へのfpos_t *pos
引数fsetpos
が実際には整数ではないため、ファイル内の任意の場所をシークするために使用できないためです。したがって、有効な値は から取得した値だけですfgetpos
。ドキュメントが言うように、
stream に関連付けられた内部ファイル位置インジケータは、 によって表される位置に設定されます。これは、 への呼び出しによって以前に取得された値を持つオブジェクト
pos
へのポインタです。fpos_t
fgetpos
( http://www.cplusplus.com/reference/cstdio/fsetpos/ )
32 ビット境界を超えて任意の場所をシークする機能だけが必要な場合は、ftello
/fseeko
を使用して#define _FILE_OFFSET_BITS 64
.
マンページから、ftell と fseek は long int 型を使用してファイル内のオフセット (位置) を表すことがわかります。したがって、long int で表現できるオフセットに限定される可能性があります。(型 long int は 2**31-1 より大きい値を保持することが保証されていないため、最大オフセットは 2 ギガバイトに制限されています)。一方、新しい fgetpos および fsetpos 関数は、特別な typedef である fpos_t を使用してオフセットを表します。この typedef の背後にある型は、適切に選択された場合、任意に大きなオフセットを表すことができるため、fgetpos と fsetpos を任意の巨大なファイルで使用できます。fgetpos と fsetpos は、マルチバイト ストリームに関連付けられた状態も記録します。
fgetpos() は fsetpos() と一緒です。そして ftell() は fseek() と一緒です。
fgetpos() は実際には ftell() に似ています。どちらも FILE* パラメーターを取り、ファイル内の何らかの位置を返すためです。ただし、スタイルはわずかに異なります。しかし、これを取得してください: fseek() のみが、ファイルの先頭から、ファイル内の現在の位置から、ファイルの最後から逆方向にシークできます (fseek() の 3 番目の引数は、SEEK_SET、SEEK_CUR、および SEEK_END です)。 )。fsetpos() はこれを行いません。fsetpos() は、fgetpos() から取得した位置に戻ることに制限されています。
ファイルをメモリに読み込みたいとしましょう。malloc() からどのくらいのヒープが必要ですか? ファイルのサイズが必要です。また、ファイルのサイズを示す関数を C 標準ライブラリでまだ見つけていませんが、一部の C コンパイラは非標準関数を追加する場合があります。たとえば、Borland Turbo C には filelength() がありました。しかし、STANDARD C ライブラリの中で filelength() を見たことがありません。
したがって、ファイルの END の前に fseek() を使用して 0 バイトにすることができます。次に、 ftell() を使用して位置をバイト単位で取得し、それに基づいてヒープ メモリの量を計算します。
ファイルサイズを取得するために他に何ができますか? fgetc() を使用して各文字を読み取り、最後まで数えることができます。しかし、 fseek() と ftell() を使用する方が優れていて簡単だと思います。
インターフェイスの定義は異なりますが、機能的には違いはありません。どちらも POSIX の一部であるため、両方とも実装されています。