SetFilePointer 関数 (fileapi.h)
指定したファイルのファイル ポインターを移動します。
この関数は、ファイル ポインターを 2 つの LONG 値に格納します。 1 つの LONG 値より大きいファイル ポインターを操作するには、 SetFilePointerEx 関数を使用する方が簡単です。
構文
DWORD SetFilePointer(
[in] HANDLE hFile,
[in] LONG lDistanceToMove,
[in, out, optional] PLONG lpDistanceToMoveHigh,
[in] DWORD dwMoveMethod
);
パラメーター
[in] hFile
ファイルへのハンドル。
ファイル ハンドルは、 GENERIC_READまたはアクセス 権GENERIC_WRITE使用して作成 する 必要があります。 詳細については、「 ファイル のセキュリティとアクセス権」を参照してください。
[in] lDistanceToMove
ファイル ポインターを移動するバイト数を指定する符号付き値の下位 32 ビット。
lpDistanceToMoveHigh が NULL でない場合、lpDistanceToMoveHigh と lDistanceToMove は、移動する距離を指定する 1 つの 64 ビット符号付き値を形成します。
lpDistanceToMoveHigh が NULL の場合、lDistanceToMove は 32 ビット符号付き値です。 lDistanceToMove の正の値を指定すると、ファイル 内のファイル ポインターが前方に移動し、負の値を指定するとファイル ポインターが戻ります。
[in, out, optional] lpDistanceToMoveHigh
移動する符号付き 64 ビット距離の上位 32 ビットへのポインター。
上位 32 ビットが不要な場合は、このポインターを NULL に設定する必要があります。
NULL でない場合、このパラメーターはファイル ポインターの新しい値の上位 DWORD も受け取ります。 詳細については、このトピックの「解説」セクションを参照してください。
[in] dwMoveMethod
ファイル ポインターの移動の開始点。
このパラメーターには、次の値のいずれかを指定できます。
値 | 意味 |
---|---|
|
開始点は 0 またはファイルの先頭です。 |
|
開始点は、ファイル ポインターの現在の値です。 |
|
開始点は、現在のファイルの終了位置です。 |
戻り値
関数が成功し、 lpDistanceToMoveHigh が NULL の場合、戻り値は新しいファイル ポインターの下位 DWORD になります。 メモ 関数が INVALID_SET_FILE_POINTER 以外の値を返す場合、 SetFilePointer の呼び出しは成功しました。 GetLastError を呼び出す必要はありません。
関数が成功し、 lpDistanceToMoveHigh が NULL でない場合、戻り値は新しいファイル ポインターの下位 DWORD で、 lpDistanceToMoveHigh には新しいファイル ポインターの上位 DWORD が 含まれます。
関数が失敗した場合、戻り値は INVALID_SET_FILE_POINTER。 詳細なエラー情報を得るには、GetLastError を呼び出します。
新しいファイル ポインターが負の値の場合、関数は失敗し、ファイル ポインターは移動されず、 GetLastError によって返されるコードは ERROR_NEGATIVE_SEEK。
lpDistanceToMoveHigh が NULL で、新しいファイル位置が 32 ビット値に収まらない場合、関数は失敗し、INVALID_SET_FILE_POINTERを返します。
注釈
hFile パラメーターの値によって識別されるファイル ポインターは、重複する読み取りおよび書き込み操作には使用されません。
hFile パラメーターは、シークしているデバイスに格納されているファイルを参照する必要があります。たとえば、ディスク ボリュームです。 SetFilePointer 関数がエラーを返さない場合でも、パイプや通信デバイスなどのシークしていないデバイスへのハンドルを使用して SetFilePointer 関数を呼び出すことはサポートされていません。 この場合の SetFilePointer 関数の動作は未定義です。
重複する操作のオフセットを指定するには
- OVERLAPPED 構造体の Offset メンバーと OffsetHigh メンバーを使用します。
hFile のファイルの種類を確認するには
- GetFileType 関数を使用します。
マルチスレッド アプリケーションでファイル ポインターを設定するときは注意してください。 共有リソースへのアクセスを同期する必要があります。 たとえば、ファイル ハンドルを共有し、ファイル ポインターを更新し、ファイルから読み取るスレッドを持つアプリケーションでは、クリティカル セクション オブジェクトまたはミューテックス オブジェクトを使用してこのシーケンスを保護する必要があります。 詳細については、「 クリティカル セクション オブジェクト 」および 「ミューテックス オブジェクト」を参照してください。
FILE_FLAG_NO_BUFFERING フラグを設定して hFile ハンドルを開いた場合、アプリケーションはファイル ポインターをセクターに合わせた位置にのみ移動できます。 セクターアラインポジションは、ボリュームセクターサイズの整数倍数である位置です。 アプリケーションは 、GetDiskFreeSpace 関数を呼び出すことによってボリューム セクター サイズを取得できます。
アプリケーションが距離を指定して SetFilePointer を呼び出して、セクターアラインされていない位置と 、FILE_FLAG_NO_BUFFERINGで開かれたハンドルになる値を移動すると、関数は失敗し、 GetLastError は ERROR_INVALID_PARAMETERを返します。
ファイル ポインターをファイルの末尾を超える位置に設定してもエラーではありません。 SetEndOfFile、WriteFile、または WriteFileEx 関数を呼び出すまで、ファイルのサイズは増加しません。 書き込み操作では、ファイルポインター位置にファイルのサイズを加えて書き込まれたバッファーのサイズを増やします。これにより、間に存在するバイトがゼロに初期化されます。
戻り値が INVALID_SET_FILE_POINTER で、 lpDistanceToMoveHigh が NULL 以外の場合、アプリケーションは GetLastError を 呼び出して、関数が成功したか失敗したかを判断する必要があります。 次のコード例は、そのシナリオを示しています。
// Case One: calling the function with lpDistanceToMoveHigh == NULL
// Try to move hFile file pointer some distance
DWORD dwPtr = SetFilePointer( hFile,
lDistance,
NULL,
FILE_BEGIN );
if (dwPtr == INVALID_SET_FILE_POINTER) // Test for failure
{
// Obtain the error code.
DWORD dwError = GetLastError() ;
// Deal with failure
// . . .
} // End of error handler
//
// Case Two: calling the function with lpDistanceToMoveHigh != NULL
// Try to move hFile file pointer a huge distance
DWORD dwPtrLow = SetFilePointer( hFile,
lDistLow,
&lDistHigh,
FILE_BEGIN );
// Test for failure
if ( dwPtrLow == INVALID_SET_FILE_POINTER &&
GetLastError() != NO_ERROR )
{
// Deal with failure
// . . .
} // End of error handler
lpDistanceToMoveHigh パラメーターは巨大なファイルを操作するために使用されますが、任意のサイズのファイルを移動する場合は、 パラメーターの値を設定する必要があります。 NULL に設定されている場合、lDistanceToMove の最大値は 2^31–2、または 2 ギガバイト未満 2 になります。これは、すべてのファイル ポインター値が符号付き値であるためです。 したがって、ファイルがそのサイズまで増加する可能性が少ない場合は、ファイルを巨大なファイルとして扱い、64 ビットのファイル ポインターを操作することをお勧めします。 NTFS ファイル システムの ファイル圧縮 と スパース ファイルを使用すると、基になるボリュームがそれほど大きくない場合でも、大きいファイルを作成できます。
lpDistanceToMoveHigh が NULL でない場合、lpDistanceToMoveHigh と lDistanceToMove は 1 つの 64 ビット符号付き値を形成します。 lDistanceToMove パラメーターは、値の下位 32 ビットとして扱われ、lpDistanceToMoveHigh は上位 32 ビットとして扱われます。つまり、lpDistanceToMoveHigh は lDistanceToMove の符号拡張です。
ファイル ポインターを 0 から 2 ギガバイトに移動するには、 lpDistanceToMoveHigh を NULL または lDistanceToMove の符号拡張に設定する必要があります。 ポインターを 2 ギガバイトを超えて移動するには、 lpDistanceToMoveHigh と lDistanceToMove を 1 つの 64 ビット数量として使用します。 たとえば、2 ギガバイトから 4 ギガバイトの範囲で移動するには、 lpDistanceToMoveHigh の内容を 0 に設定し、 lDistanceToMove の負符号拡張の場合は -1 に設定します。
64 ビット ファイル ポインターを操作するには、 LONG を宣言し、それを 64 ビット ファイル ポインターの上半分として扱い、そのアドレスを lpDistanceToMoveHigh に渡します。 つまり、2 つの異なる変数を論理ユニットとして扱う必要があり、エラーが発生する可能性があります。 LARGE_INTEGER構造体を使用して 64 ビット値を作成し、共用体の適切な要素を使用して 2 つの 32 ビット値を渡すのが最善です。
また、関数を使用して SetFilePointer へのインターフェイスを非表示にすることをお勧めします。 次のコード例は、そのシナリオを示しています。
__int64 myFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
{
LARGE_INTEGER li;
li.QuadPart = distance;
li.LowPart = SetFilePointer (hf,
li.LowPart,
&li.HighPart,
MoveMethod);
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError()
!= NO_ERROR)
{
li.QuadPart = -1;
}
return li.QuadPart;
}
SetFilePointer を使用して、ファイルの長さを決定できます。 これを行うには、dwMoveMethod に FILE_END を使用し、位置 0 をシークします。 返されるファイル オフセットは、ファイルの長さです。 ただし、この方法では、プログラムがその場所に戻ることができるように、現在のファイル ポインターを保存できないなど、意図しない副作用が発生する可能性があります。 代わりに GetFileSize を 使用することをお勧めします。
SetFilePointer 関数を使用して、現在のファイル ポインターの位置を照会することもできます。 これを行うには、 FILE_CURRENT の移動方法と 0 の距離を指定します。
Windows 8 と Windows Server 2012 では、この関数は、次のテクノロジによってサポートされています。
テクノロジ | サポートされています |
---|---|
サーバー メッセージ ブロック (SMB) 3.0 プロトコル | はい |
SMB 3.0 Transparent Failover (TFO) | はい |
スケールアウト ファイル共有 (SO) を使う SMB 3.0 | はい |
クラスターの共有ボリューム ファイル システム (CsvFS) | はい |
Resilient File System (ReFS) | はい |
例
ファイルを追加するコード例については、「 1 つのファイルを別のファイルに追加する」を参照してください。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows XP [デスクトップ アプリ | UWP アプリ] |
サポートされている最小のサーバー | Windows Server 2003 [デスクトップ アプリのみ | UWP アプリ] |
対象プラットフォーム | Windows |
ヘッダー | fileapi.h (Windows.h を含む) |
Library | Kernel32.lib |
[DLL] | Kernel32.dll |