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.
DWORD SetFilePointer(
[in] HANDLE hFile,
[in] LONG lDistanceToMove,
[in, out, optional] PLONG lpDistanceToMoveHigh,
[in] DWORD dwMoveMethod
);
[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.
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.
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
- Verwenden Sie die Elemente Offset und OffsetHigh der OVERLAPPED-Struktur .
So bestimmen Sie den Dateityp für hFile
- Verwenden Sie die GetFileType-Funktion .
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 |
Ein Codebeispiel für das Anfügen von Dateien finden Sie unter Anfügen einer Datei an eine andere Datei.
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 |