setFilePointer 函式 (fileapi.h)

移動指定檔案的檔案指標。

此函式會將檔案指標儲存在兩 個LONG 值中。 若要使用大於單一 LONG 值的檔案指標,使用 SetFilePointerEx 函 式會比較容易。

語法

DWORD SetFilePointer(
  [in]                HANDLE hFile,
  [in]                LONG   lDistanceToMove,
  [in, out, optional] PLONG  lpDistanceToMoveHigh,
  [in]                DWORD  dwMoveMethod
);

參數

[in] hFile

檔案的句柄。

您必須使用 GENERIC_READGENERIC_WRITE 訪問許可權來建立檔句柄。 如需詳細資訊,請參閱 檔案安全性和訪問許可權

[in] lDistanceToMove

帶正負號值的低順序 32 位,指定要移動檔案指標的位元元組數目。

如果 lpDistanceToMoveHigh 不是 NULL,lpDistanceToMoveHighlDistanceToMove 會形成單一 64 位帶正負號的值,指定移動距離。

如果 lpDistanceToMoveHighNULL,lDistanceToMove 是 32 位帶正負號的值。 lDistanceToMove 的正值會將檔案指標往前移動,負值會將檔案指標移回。

[in, out, optional] lpDistanceToMoveHigh

要移動之帶正負號 64 位距離之高階 32 位的指標。

如果您不需要高階 32 位,此指標必須設定為 NULL

若不是 NULL,此參數也會收到檔案指標新值的高序 DWORD 。 如需詳細資訊,請參閱本主題中的一節。

[in] dwMoveMethod

檔案指標移動的起點。

此參數可以是下列其中一個值。

意義
FILE_BEGIN
0
起點為零或檔案的開頭。
FILE_CURRENT
1
起點是檔案指標的目前值。
FILE_END
2
起點是目前的檔案結束位置。

傳回值

如果函式成功且 lpDistanceToMoveHighNULL,則傳回值會是新檔案指標的低序 DWORD注意 如果函式傳回 INVALID_SET_FILE_POINTER以外的值, 則 SetFilePointer 的呼叫已成功。 您不需要呼叫 GetLastError

如果函式成功且 lpDistanceToMoveHigh 不是 NULL,則傳回值是新檔案指標的低序 DWORD而 lpDistanceToMoveHigh 包含新檔案指標的高順序 DWORD

如果函式失敗,傳回值會 INVALID_SET_FILE_POINTER。 若要取得擴充的錯誤資訊,請呼叫 GetLastError

如果新的檔案指標是負值,則函式會失敗、檔案指標不會移動,而且 GetLastError 傳回的程式代碼會 ERROR_NEGATIVE_SEEK

如果 lpDistanceToMoveHighNULL ,而且新的檔案位置不符合 32 位的值,則函式會失敗並傳回 INVALID_SET_FILE_POINTER

注意 因為 INVALID_SET_FILE_POINTER 是新檔案指標之低序 DWORD 的有效值,所以您必須檢查函式的傳回值,以及 GetLastError 傳回的錯誤碼,以判斷是否已發生錯誤。 如果發生錯誤,則會INVALID_SET_FILE_POINTERSetFilePointer 的傳回值,而 GetLastError 會傳回NO_ERROR以外的值。 如需示範如何檢查失敗的程式代碼範例,請參閱本主題中的一節。
 

備註

hFile 參數值所識別的檔案指標不會用於重疊的讀取和寫入作業。

hFile 參數必須參考儲存在搜尋裝置上的檔案;例如,磁碟區。 即使 SetFilePointer 函式可能不會傳回錯誤,但不支援呼叫具有非搜尋裝置句柄的 SetFilePointer 函式,例如管道或通訊裝置。 在此情況下 ,SetFilePointer 函式的行為是未定義的。

指定重迭作業的位移

  • 使用 OVERLAPPED 結構的 Offset 和OffsetHigh 成員。

判斷 hFile 的文件類型

如需如何判斷檔案指標位置的資訊,請參閱 放置檔案指標

當您在多線程應用程式中設定檔案指標時,請小心。 您必須同步存取共享資源。 例如,具有共用檔句柄、更新檔案指標,以及從檔案讀取之線程的應用程式必須使用重要區段物件或 mutex 物件來保護此序列。 如需詳細資訊,請參閱 Critical Section ObjectsMutex Objects

如果 hFile 句柄是以 設定FILE_FLAG_NO_BUFFERING 旗標開啟,則應用程式只能將檔案指標移至扇區對齊的位置。 扇區對齊位置是一個整數的磁碟區扇區大小倍數的位置。 應用程式可以藉由呼叫 GetDiskFreeSpace 函式來取得磁碟區扇區大小。

如果應用程式呼叫具有距離的 SetFilePointer 來行動導致位置不對齊且句柄以 FILE_FLAG_NO_BUFFERING開啟的值,則函式會失敗,而 GetLastError 會傳回 ERROR_INVALID_PARAMETER

將檔案指標設定為檔案結尾以外的位置並無錯誤。 在您呼叫 SetEndOfFileWriteFile 或 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 GB 小於 2,因為所有檔案指標值都是帶正負號的值。 因此,如果檔案甚至有機會增加至該大小,最好將檔案視為大型檔案,並使用64位檔案指標。 在NTFS檔系統和疏鬆檔案上使用檔案壓縮時,即使基礎磁碟區不是非常大,還是可能會有大型的檔案。

如果 lpDistanceToMoveHigh 不是 NULL則 lpDistanceToMoveHighlDistanceToMove 形成單一 64 位帶正負號的值。 lDistanceToMove 參數會被視為值的低序 32 位,而 lpDistanceToMoveHigh 則視為高序 32 位,這表示 lpDistanceToMoveHighlDistanceToMove 的正負號延伸。

若要將檔案指標從零移至 2 GB,lpDistanceToMoveHigh 必須設定為 NULLlDistanceToMove 的符號擴展名。 若要移動超過 2 GB 的指標,請使用 lpDistanceToMoveHighlDistanceToMove 作為單一 64 位數量。 例如,若要在 2 GB 到 4 GB 的範圍內移動,請將 lpDistanceToMoveHigh 的內容設定為零,或設定為 –1 表示 lDistanceToMove 的負號延伸。

若要使用 64 位檔案指標,您可以宣告 LONG、將 視為 64 位檔案指標的上半部,並在 lpDistanceToMoveHigh 中傳遞其位址。 這表示您必須將兩個不同的變數視為邏輯單元,這可能會導致錯誤。 最好使用 LARGE_INTEGER 結構來建立 64 位值,並使用等位的適當元素傳遞兩個 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,並搜尋至位置零。 傳回的檔案位移是檔案的長度。 不過,這個做法可能會有非預期的副作用,例如,無法儲存目前的檔案指標,讓程式可以返回該位置。 最好改用 GetFileSize

您也可以使用 SetFilePointer 函 式來查詢目前的檔案指標位置。 若要這樣做,請指定 FILE_CURRENT 的移動方法,以及零的距離。

在 Windows 8 和 Windows Server 2012 中,下列技術支援此函式。

技術 支援
伺服器消息塊 (SMB) 3.0 通訊協定 Yes
SMB 3.0 透明故障轉移 (TFO) Yes
具有向外延展檔案共用的SMB 3.0 (SO) Yes
叢集共用磁碟區文件系統 (CsvFS) Yes
彈性檔案系統 (ReFS)
 

範例

如需附加檔案的程式代碼範例,請參閱 將一個檔案附加至另一個檔案

規格需求

需求
最低支援的用戶端 Windows XP [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 fileapi.h (包含 Windows.h)
程式庫 Kernel32.lib
DLL Kernel32.dll

另請參閱

檔案管理功能

GetDiskFreeSpace

GetFileSize

GetFileType

ReadFile

ReadFileEx

SetEndOfFile

SetFilePointerEx

WriteFile

WriteFileEx