fseek() - ファイル位置の変更

標準

標準/拡張機能 C/C++ 依存項目

ISO C
POSIX.1
XPG4
XPG4.2
C99
Single UNIX Specification、バージョン 3
Language Environment

両方  

形式

#include <stdio.h>

int fseek(FILE *stream, long int offset, int origin);

#define _OPEN_SYS_UNLOCKED_EXT 1
#include <stdio.h>

int fseek_unlocked(FILE *stream, long int offset, int origin);

機能説明

fseek() 関数は、stream に関連する現行のファイル位置を、ファイル内の新しい 位置へ変更します。stream での次の操作は、新しい位置で行われます。 更新用にオープンされた stream では、次の操作は読み取り操作または書き込み操作のいずれかです。

オリジンは stdio.h で定義された以下の定数のいずれかでなければなりません。
オリジン
定義
SEEK_SET
ファイルの始め
SEEK_CUR
ファイル・ポインターの現在位置
SEEK_END
ファイルの終わり

正常終了した場合、fseek() 関数は、origin が SEEK_END のときでも、EOF 標識をクリア し、先行する ungetc() または ungetwc() 関数の同じストリームに対する 影響を取り消します。

fseek() 関数または fsetpos() 関数の呼び出しが無効な場合、その 呼び出しはフラッシュとして扱われ、ungetc 文字は廃棄されます。

バイナリー・ストリームの動作: ANSI では、ftell() 関数と fseek() 関数の両方についてバイナリー・ストリームが相対バイト・オフセットを使用すると記述しています。z/OS® XL C/C++ ではこれに該当しますが、可変長レコードを持つレコード指向ファイルの場合は該当しません。このようなタイプのファイルの場合、デフォルトの動作では、SEEK_SET の起点を使用して、ftell() 関数と fseek() 関数についてエンコード・オフセットが使用されます。

エンコード・オフセットでは、ユーザーは、直前の ftell() 関数呼び出しで記録された位置、または位置 0 へのシークだけに制限されます。このようなタイプのファイルに相対バイト・オフセットを使用したい場合は、BYTESEEK fopen() 関数オプションを使用してファイルをオープンするか、またはオープンする前に _EDC_BYTE_SEEK 環境変数を設定することができます。

相対バイト・オフセットで、独自のオフセットを計算できます。オフセットが EOF を超えると、ファイルは NULL で拡張されます。次に新しいデータを書き込む場合に、ファイルが NULL でのみ拡張される、z/OS UNIX ファイルは例外です。これは、POSIX の下で、z/OS UNIX ファイルを使用する場合にも該当します。HFS ファイルは、次に新しいデータを書き込む場合、NULL でのみ拡張されます。

ファイルの先頭より前の位置に変更しようとすると、fseek() 関数は 失敗します。

エンコード・オフセットまたは相対オフセットのどちらが ftell() 関数で 戻されるかに関係なく、SEEK_CUR および SEEK_END を使用するときには、相対オフセットを指定できます。

新しい位置がファイルの先頭より前であれば、fseek() 関数は失敗します。相対オフセットが EOF を超えて位置付けられる場合は、ファイルは NULL で 埋め込まれます。次の新規データの書き込みまで埋め込みが起こらない、z/OS UNIX ファイルを使用する POSIX の場合は例外です。

テキスト・ストリームの動作: テキスト・ストリームの場合、ftell() 関数は、エンコード・オフセットを戻します。起点を SEEK_SET にしてシークすると、位置 0 または直前の ftell() 関数呼び出しで戻された位置へのシークだけに制限されます。

独自の位置を計算しようとしても、その計算はサポートされず、結果的に無効な位置になって fseek() 関数が失敗する場合があります。

SEEK_CUR または SEEK_END を使用している場合、オフセットは相対バイト・オフセットになります。ファイルの開始より前、または EOF を超えてシークしようとすると、結果は 失敗に終わります。

レコード入出力の動作: type=record オープン・モード・パラメーターを使用するレコード入出力のためにオープンされたファイルの 場合、ftell() 関数は、相対レコード番号を戻します。SEEK_SET、SEEK_CUR、および SEEK_END のオリジンの場合は、オフセットは相対レコード 番号になります。

最初のレコードより前、または EOF を超えてシークしようとすると、結果は 失敗に終わります。

ブロック入出力の動作: type=blocked オープン・モード・パラメーターを使用するブロック入出力のためにオープンされたファイルの場合、ftell() 関数は、相対ブロック番号を戻します。SEEK_SET、SEEK_CUR、および SEEK_END のオリジンの場合は、オフセットは相対ブロック番号になります。

最初のブロックより前、または EOF を超えてシークしようとすると、結果は失敗に終わります。

ワイド指向ストリームの動作: 上記の制限のすべてが、すべてのタイプのワイド指向ストリームに適用されます。

マルチボリューム・データ・セットのパフォーマンス: 一般的に fgetpos() 関数および fsetpos() 関数を使用すると、位置変更のパフォーマンスが ftell() 関数および fseek() 関数と比較してよくなります (マルチボリューム・データ・セットで作業する場合)。

MVS データ・セット、VSAM データ・セット、および z/OS UNIX ファイルの大規模ファイル・サポート: AMODE 31 C/C++ アプリケーションの場合、fseek() 関数は符号付き 4 バイトのオフセットを受け入れます。そのため、この関数は、2 GB - 1 を超えるオフセットに直接または相対的に位置付けるのに使用できません。位置変更の制限を回避するために、AMODE 31 C/C++ アプリケーションでは、ヘッダーが組み込まれる前に _LARGE_FILES フィーチャー・テスト・マクロを定義し、fseek() 関数を fseeko() 関数で置き換える必要があります。AMODE 64 C/C++ アプリケーションの場合、大規模ファイルでの fseek() 関数の使用には制限はありません。AMODE 64 バージョンは、符号付き 8 バイトのオフセットを自動的に受け入れます。

使用上の注意

  1. ワイド指向ファイル内での位置変更や、更新の実行は、決して行わないでください。更新部分がマルチバイト・ストリングや文字の一部を上書きすると、以降のデータが無効になるのを予測することができなくなるためです。例えば、シフトアウト文字を上書きするデータを不注意に追加する可能性も あります。以下のデータは、シフトアウトがあることを想定していますが、初期シフト状態であるかのように扱われる場合は無効です。ファイルの終わりに位置変更したり、新規データを追加したりするのは安全です。
  2. SEEK_CUR を指定すると、ungetc() 関数または ungetwc() 関数で プッシュ・バックされた文字は、ファイル・ポインターの現在位置 (シークの 開始点) をバックアップします。シークは、位置変更前に、戻された文字を廃棄しますが、開始点には影響があります。ungetc() または ungetwc() 関数呼び出し後の fseek() 関数の呼び出しに関する詳細は、ungetc() - 入力ストリームへの文字のプッシュおよび ungetwc() - ストリームへのワイド文字のプッシュを参照してください。
  3. _EDC_COMPAT 環境変数によって、fseek() は、ungetc() 関数また は ungetwc() 関数の影響を無視するようになります。詳しくは、「z/OS XL C/C++ プログラミング・ガイド」で環境変数に関するトピックを参照してください。
  4. fseek_unlocked() 関数は、スレッド・セーフでないことを除いて、機能的に fseek() 関数と 等価です。fseek() 関数をマルチスレッド・アプリケーション内で安全に使用できるのは、 flockfile() 関数または ftrylockfile() 関数のどちらかへの呼び出しが成功した後のように、 呼び出しスレッドが (FILE*) オブジェクトを所有している間に、この関数を呼び出す場合だけです。

戻り値

正常にポインターを移動できた場合、fseek() 関数は 0 を戻します。

正常に終了しなかった場合、または端末やプリンターのような、シークできないデバイスである場合、fseek() 関数は戻り値をゼロ以外に戻します。

XPG4.2 の特殊な動作: 正常に実行されなかった場合、fseek() 関数は -1 を戻して、errno を次のいずれかの 値に設定します。
エラー・コード
説明
EOVERFLOW
生成されるファイルのオフセットは、long 型のオブジェクトでは正しく表すことができない値になります。
注: 環境変数 _EDC_EOVERFLOW は、z/OS UNIX ファイルの EOVERFLOW 条件の検出に関する fseek() 関数の動作 を制御するために使用できます。デフォルトでは、引き続き fseek() 関数は、ftell() 関数が戻すことのできる 位置を越えて、位置付けることが可能です。_EDC_EOVERFLOW が YES に設定された場合、fseek() 関数は、 ftell() 関数が新しい位置を戻すことが可能かどうか確認します。
ESPIPE
ストリームの基礎ファイル・タイプは、PIPE またはソケットです。

/* This example opens a file myfile.dat for reading.
   After performing input operations (not shown), it moves the file
   pointer to the beginning of the file.
 */
#include <stdio.h>

int main(void)
{
   FILE *stream;
   int result;

   if (stream = fopen("myfile.dat", "r"))
   { /* successful */

   if (fseek(stream, 0L, SEEK_SET));  /* moves pointer to   */
                                  /* the beginning of the file */
   { /* if not equal to 0
             then error ...    */
   }
   else {
       /* fseek() successful  */
   }
}

関連情報