SetFilePointer-Funktion (fileapi.h)

Verschiebt den Dateizeiger der angegebenen Datei.

Diese Funktion speichert den Dateizeiger in zwei LONG-Werten . Um mit Dateizeigern zu arbeiten, die größer als ein einzelner LONG-Wert sind, ist es einfacher, die SetFilePointerEx-Funktion zu verwenden.

Syntax

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

Parameter

[in] hFile

Ein Handle zur Datei.

Das Dateihandle muss mit dem zugriffsrecht GENERIC_READ oder GENERIC_WRITE erstellt werden. Weitere Informationen finden Sie unter Dateisicherheit und Zugriffsrechte.

[in] lDistanceToMove

Die 32-Bits in niedriger Reihenfolge eines vorzeichenierten Werts, der die Anzahl der Bytes angibt, die den Dateizeiger verschieben sollen.

Wenn lpDistanceToMoveHigh nicht NULL ist, bilden lpDistanceToMoveHigh und lDistanceToMove einen einzelnen 64-Bit-Vorzeichenwert, der die zu verschiebende Entfernung angibt.

Wenn lpDistanceToMoveHighNULL ist, ist lDistanceToMove ein 32-Bit-Wert mit Vorzeichen. Ein positiver Wert für lDistanceToMove verschiebt den Dateizeiger in der Datei nach vorne, und ein negativer Wert verschiebt den Dateizeiger zurück.

[in, out, optional] lpDistanceToMoveHigh

Ein Zeiger auf die hohen 32-Bits des vorzeichenierten 64-Bit-Abstands, der verschoben werden soll.

Wenn Sie die hohen 32-Bits nicht benötigen, muss dieser Zeiger auf NULL festgelegt werden.

Wenn nicht NULL, empfängt dieser Parameter auch die hohe DWORD-Reihenfolge des neuen Werts des Dateizeigers. Weitere Informationen finden Sie im Abschnitt Hinweise in diesem Thema.

[in] dwMoveMethod

Der Startpunkt für die Dateizeigerverschiebung.

Dieser Parameter kann einen der folgenden Werte annehmen.

Wert Bedeutung
FILE_BEGIN
0
Der Startpunkt ist 0 oder der Anfang der Datei.
FILE_CURRENT
1
Der Startpunkt ist der aktuelle Wert des Dateizeigers.
FILE_END
2
Der Startpunkt ist die aktuelle Position am Ende der Datei.

Rückgabewert

Wenn die Funktion erfolgreich ist und lpDistanceToMoveHighNULL ist, ist der Rückgabewert der DWORD mit niedriger Reihenfolge des neuen Dateizeigers. Hinweis Wenn die Funktion einen anderen Wert als INVALID_SET_FILE_POINTER zurückgibt, ist der Aufruf von SetFilePointer erfolgreich. Sie müssen GetLastError nicht aufrufen.

Wenn die Funktion erfolgreich ist und lpDistanceToMoveHigh nicht NULL ist, ist der Rückgabewert der DWORD-Wert mit niedriger Reihenfolge des neuen Dateizeigers, und lpDistanceToMoveHigh enthält die hohe DWORD-Reihenfolge des neuen Dateizeigers.

Wenn die Funktion fehlschlägt, wird der Rückgabewert INVALID_SET_FILE_POINTER. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.

Wenn ein neuer Dateizeiger ein negativer Wert ist, schlägt die Funktion fehl, der Dateizeiger wird nicht verschoben, und der von GetLastError zurückgegebene Code wird ERROR_NEGATIVE_SEEK.

Wenn lpDistanceToMoveHighNULL ist und die neue Dateiposition nicht in einen 32-Bit-Wert passt, schlägt die Funktion fehl und gibt INVALID_SET_FILE_POINTER zurück.

Hinweis Da INVALID_SET_FILE_POINTER ein gültiger Wert für die DWORD-Niedrigreihenfolge des neuen Dateizeigers ist, müssen Sie sowohl den Rückgabewert der Funktion als auch den von GetLastError zurückgegebenen Fehlercode überprüfen, um zu ermitteln, ob ein Fehler aufgetreten ist. Wenn ein Fehler aufgetreten ist, wird der Rückgabewert von SetFilePointerINVALID_SET_FILE_POINTER , und GetLastError gibt einen anderen Wert als NO_ERROR zurück. Ein Codebeispiel, das veranschaulicht, wie Sie nach Fehlern suchen, finden Sie im Abschnitt Hinweise in diesem Thema.
 

Hinweise

Der Dateizeiger, der durch den Wert des hFile-Parameters identifiziert wird, wird nicht für überlappende Lese- und Schreibvorgänge verwendet.

Der hFile-Parameter muss auf eine Datei verweisen, die auf einem suchenden Gerät gespeichert ist. Beispielsweise ein Datenträgervolume. Das Aufrufen der SetFilePointer-Funktion mit einem Handle für ein nicht suchendes Gerät, z. B. eine Pipe oder ein Kommunikationsgerät, wird nicht unterstützt, auch wenn die SetFilePointer-Funktion möglicherweise keinen Fehler zurückgibt. Das Verhalten der SetFilePointer-Funktion ist in diesem Fall nicht definiert.

So geben Sie den Offset für überlappende Vorgänge an

So bestimmen Sie den Dateityp für hFile

Informationen zum Bestimmen der Position eines Dateizeigers finden Sie unter Positionieren eines Dateizeigers.

Seien Sie vorsichtig, wenn Sie einen Dateizeiger in einer Multithreadanwendung festlegen. Sie müssen den Zugriff auf freigegebene Ressourcen synchronisieren. Beispielsweise muss eine Anwendung mit Threads, die ein Dateihandle gemeinsam nutzen, den Dateizeiger aktualisieren und aus der Datei lesen, diese Sequenz schützen, indem sie ein kritisches Abschnittsobjekt oder ein Mutex-Objekt verwendet. Weitere Informationen finden Sie unter Kritische Abschnittsobjekte und Mutex-Objekte.

Wenn das hFile-Handle mit dem FILE_FLAG_NO_BUFFERING-Flags geöffnet wird, kann eine Anwendung den Dateizeiger nur an sektororientierte Positionen verschieben. Eine sektororientierte Position ist eine Position, die ein ganzes Vielfaches der Volumensektorgröße darstellt. Eine Anwendung kann eine Volumensektorgröße abrufen, indem sie die GetDiskFreeSpace-Funktion aufruft.

Wenn eine Anwendung SetFilePointer mit Abstand aufruft, um Werte zu verschieben, die zu einer nicht sektororientierten Position führen, und einem Handle, das mit FILE_FLAG_NO_BUFFERING geöffnet wird, schlägt die Funktion fehl, und GetLastError gibt ERROR_INVALID_PARAMETER zurück.

Es ist kein Fehler, einen Dateizeiger auf eine Position außerhalb des Endes der Datei festzulegen. Die Größe der Datei wird erst erhöht, wenn Sie die Funktion SetEndOfFile, WriteFile oder WriteFileEx aufrufen. Ein Schreibvorgang erhöht die Größe der Datei auf die Dateizeigerposition und die Größe des geschriebenen Puffers, was dazu führt, dass die dazwischen liegenden Bytes 0 initialisiert werden.

Wenn der Rückgabewert INVALID_SET_FILE_POINTER ist und lpDistanceToMoveHigh nicht NULL ist, muss eine Anwendung GetLastError aufrufen, um festzustellen, ob die Funktion erfolgreich war oder nicht. Im folgenden Codebeispiel wird dieses Szenario veranschaulicht.

  // 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

Obwohl der Parameter lpDistanceToMoveHigh verwendet wird, um große Dateien zu bearbeiten, sollte der Wert des Parameters beim Verschieben von Dateien beliebiger Größe festgelegt werden. Wenn es auf NULL festgelegt ist, hat lDistanceToMove einen Maximalwert von 2^31–2 oder 2 Gigabyte weniger 2, da alle Dateizeigerwerte signierte Werte sind. Wenn daher die Chance besteht, dass die Datei auf diese Größe ansteigt, ist es am besten, die Datei als riesige Datei zu behandeln und mit 64-Bit-Dateizeigern zu arbeiten. Mit der Dateikomprimierung im NTFS-Dateisystem und sparse-Dateien ist es möglich, Dateien zu verwenden, die groß sind, auch wenn das zugrunde liegende Volume nicht sehr groß ist.

Wenn lpDistanceToMoveHigh nicht NULL ist, bilden lpDistanceToMoveHigh und lDistanceToMove einen einzelnen 64-Bit-Vorzeichenwert. Der Parameter lDistanceToMove wird als niedrigwertige 32 Bits des Werts und lpDistanceToMoveHigh als hochgeordnete 32 Bits behandelt, was bedeutet, dass lpDistanceToMoveHigh eine Zeichenerweiterung von lDistanceToMove ist.

Um den Dateizeiger von null auf 2 Gigabyte zu verschieben, muss lpDistanceToMoveHigh entweder auf NULL oder eine Zeichenerweiterung von lDistanceToMove festgelegt werden. Um den Zeiger mehr als 2 Gigabyte zu verschieben, verwenden Sie lpDistanceToMoveHigh und lDistanceToMove als einzelne 64-Bit-Menge. Um beispielsweise im Bereich von 2 Gigabyte bis 4 Gigabyte zu verschieben, legen Sie den Inhalt von lpDistanceToMoveHigh auf Null oder auf –1 für eine Negative-Zeichenerweiterung von lDistanceToMove fest.

Um mit 64-Bit-Dateizeigern zu arbeiten, können Sie einen LONG deklarieren, ihn als obere Hälfte des 64-Bit-Dateizeigers behandeln und dessen Adresse in lpDistanceToMoveHigh übergeben. Dies bedeutet, dass Sie zwei verschiedene Variablen als logische Einheit behandeln müssen, was zu einem Fehler führen kann. Es ist am besten, die LARGE_INTEGER-Struktur zu verwenden, um einen 64-Bit-Wert zu erstellen und die beiden 32-Bit-Werte mit den entsprechenden Elementen der Union zu übergeben.

Außerdem ist es am besten, eine Funktion zu verwenden, um die Schnittstelle auf SetFilePointer auszublenden. Im folgenden Codebeispiel wird dieses Szenario veranschaulicht.

__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;
}

Sie können SetFilePointer verwenden, um die Länge einer Datei zu bestimmen. Verwenden Sie dazu FILE_END für dwMoveMethod , und suchen Sie nach der Position null. Der zurückgegebene Dateioffset ist die Länge der Datei. Diese Vorgehensweise kann jedoch unbeabsichtigte Nebenwirkungen haben, z. B. fehler beim Speichern des aktuellen Dateizeigers, sodass das Programm an diesen Speicherort zurückkehren kann. Es ist am besten, stattdessen GetFileSize zu verwenden.

Sie können auch die SetFilePointer-Funktion verwenden, um die aktuelle Dateizeigerposition abzufragen. Geben Sie dazu eine Move-Methode von FILE_CURRENT und einen Abstand von 0 an.

Unter Windows 8 und Windows Server 2012 wird diese Funktion von den folgenden Technologien unterstützt.

Technologie Unterstützt
SMB 3.0-Protokoll (Server Message Block) Ja
SMB 3.0 Transparent Failover (TFO) Ja
SMB 3.0 mit Dateifreigaben mit horizontaler Skalierung (SO) Ja
Dateisystem mit freigegebenen Clustervolumes (CsvFS) Ja
Robustes Dateisystem (Resilient File System, ReFS) Ja
 

Beispiele

Ein Codebeispiel für das Anfügen von Dateien finden Sie unter Anfügen einer Datei an eine andere Datei.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows XP [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile fileapi.h (Einschließen von Windows.h)
Bibliothek Kernel32.lib
DLL Kernel32.dll

Siehe auch

Dateiverwaltungsfunktionen

GetDiskFreeSpace

GetFileSize

GetFileType

ReadFile

ReadFileEx

SetEndOfFile

SetFilePointerEx

WriteFile

WriteFileEx