WriteFileEx-Funktion (fileapi.h)
Schreibt Daten in die angegebene Datei oder auf das angegebene Eingabe-/Ausgabegerät (E/A). Der Abschlussstatus wird asynchron durch Aufruf der angegebenen Abschlussroutine gemeldet, wenn der Schreibvorgang abgeschlossen oder abgebrochen wurde und sich der aufrufende Thread in einem warnbaren Wartezustand befindet.
Verwenden Sie die WriteFile-Funktion , um Daten synchron in eine Datei oder ein Gerät zu schreiben.
Syntax
BOOL WriteFileEx(
[in] HANDLE hFile,
[in, optional] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[in, out] LPOVERLAPPED lpOverlapped,
[in] LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
Parameter
[in] hFile
Ein Handle für die Datei oder das E/A-Gerät (z. B. eine Datei, einen Dateistream, einen physischen Datenträger, ein Volume, einen Konsolenpuffer, ein Bandlaufwerk, einen Socket, eine Kommunikationsressource, ein Maillot oder eine Pipe).
Dieser Parameter kann ein beliebiges Handle sein, das mit dem flag FILE_FLAG_OVERLAPPED von der CreateFile-Funktion geöffnet wird, oder ein Sockethandle, das von der Socket- oder Acceptfunktion zurückgegeben wird.
Ordnen Sie diesem Handle keinen E/A-Abschlussport zu. Weitere Informationen finden Sie im Abschnitt mit Hinweisen.
Dieses Handle muss auch über das zugriffsrecht GENERIC_WRITE verfügen. Weitere Informationen zu Zugriffsrechten finden Sie unter Dateisicherheit und Zugriffsrechte.
[in, optional] lpBuffer
Ein Zeiger auf den Puffer, der die Daten enthält, die in die Datei oder das Gerät geschrieben werden sollen.
Dieser Puffer muss für die Dauer des Schreibvorgangs gültig bleiben. Der Aufrufer darf diesen Puffer erst verwenden, wenn der Schreibvorgang abgeschlossen ist.
[in] nNumberOfBytesToWrite
Die Anzahl der Bytes, die in die Datei oder das Gerät geschrieben werden sollen.
Der Wert 0 (null) gibt einen NULL-Schreibvorgang an. Das Verhalten eines NULL-Schreibvorgangs hängt vom zugrunde liegenden Dateisystem ab.
Pipeschreibvorgänge in einem Netzwerk sind auf 65.535 Bytes pro Schreibvorgang beschränkt. Weitere Informationen zu Rohren finden Sie im Abschnitt Hinweise.
[in, out] lpOverlapped
Ein Zeiger auf eine OVERLAPPED-Datenstruktur , die Daten bereitstellt, die während des überlappenden (asynchronen) Schreibvorgangs verwendet werden sollen.
Für Dateien, die Byteoffsets unterstützen, müssen Sie einen Byteoffset angeben, an dem mit dem Schreiben in die Datei begonnen werden soll. Sie geben diesen Offset an, indem Sie die Elemente Offset und OffsetHigh der OVERLAPPED-Struktur festlegen. Für Dateien oder Geräte, die byteoffsets nicht unterstützen, werden Offset und OffsetHigh ignoriert.
Um an das Ende der Datei zu schreiben, geben Sie sowohl die Offset - als auch die OffsetHigh-Member der OVERLAPPED-Struktur als an 0xFFFFFFFF
. Dies entspricht funktional dem Aufruf der CreateFile-Funktion , um hFile mit FILE_APPEND_DATA Zugriff zu öffnen.
Die WriteFileEx-Funktion ignoriert den hEvent-Member der OVERLAPPED-Struktur. Eine Anwendung kann dieses Element für eigene Zwecke im Kontext eines WriteFileEx-Aufrufs verwenden. WriteFileEx signalisiert den Abschluss des Schreibvorgangs, indem die Abschlussroutine, auf die von lpCompletionRoutine verwiesen wird, aufgerufen oder eine Warteschlange angestellt wird, sodass kein Ereignishandle benötigt wird.
Die WriteFileEx-Funktion verwendet die Member Internal und InternalHigh der OVERLAPPED-Struktur . Sie sollten den Wert dieser Member nicht ändern.
Die OVERLAPPED-Datenstruktur muss für die Dauer des Schreibvorgangs gültig bleiben. Es sollte sich nicht um eine Variable handelt, die den Gültigkeitsbereich sprengen kann, während der Schreibvorgang aussteht.
[in] lpCompletionRoutine
Ein Zeiger auf eine Vervollständigungsroutine, die aufgerufen werden soll, wenn der Schreibvorgang abgeschlossen wurde und sich der aufrufende Thread in einem warnbaren Wartezustand befindet. Weitere Informationen zu dieser Vervollständigungsroutine finden Sie unter FileIOCompletionRoutine.
Rückgabewert
Wenn die Funktion erfolgreich ist, ist der Rückgabewert ungleich Null.
Wenn die Funktion fehlerhaft ist, ist der Rückgabewert null. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.
Wenn die WriteFileEx-Funktion erfolgreich ist, hat der aufrufende Thread einen asynchronen E/A-Vorgang ausstehend: der überlappende Schreibvorgang in die Datei. Wenn dieser E/A-Vorgang abgeschlossen ist und der aufrufende Thread in einem warnbaren Wartezustand blockiert wird, ruft das Betriebssystem die Funktion auf, auf die von lpCompletionRoutine verwiesen wird, und die Wartezeit wird mit dem Rückgabecode abgeschlossen WAIT_IO_COMPLETION
.
Wenn die Funktion erfolgreich ist und der Dateischreibvorgang abgeschlossen ist, sich der aufrufende Thread jedoch nicht in einem warnbaren Wartezustand befindet, wird der Aufruf von *lpCompletionRoutine in die Warteschlange des Systems eingereiht und der Aufruf gehalten, bis der aufrufende Thread in einen warnbaren Wartezustand wechselt. Weitere Informationen zu warnbaren Wartezuständen und überlappenden Eingabe-/Ausgabevorgängen finden Sie unter Informationen zur Synchronisierung.
Hinweise
Wenn Sie WriteFileEx verwenden, sollten Sie GetLastError auch dann überprüfen, wenn die Funktion "success" zurückgibt, um nach Bedingungen zu suchen, die erfolgreich sind, aber ein Ergebnis aufweisen, über das Sie vielleicht wissen möchten. Beispielsweise gibt ein Pufferüberlauf beim Aufrufen von WriteFileEx zurück TRUE
, aber GetLastError meldet den Überlauf mit ERROR_MORE_DATA
. Wenn der Funktionsaufruf erfolgreich ist und keine Warnungsbedingungen vorhanden sind, gibt GetLastError zurück ERROR_SUCCESS
.
Die WriteFileEx-Funktion schlägt fehl, wenn der hFile-Parameter einem E/A-Abschlussport zugeordnet ist. Um Schreibvorgänge mit diesem Handletyp auszuführen, verwenden Sie die WriteFile-Funktion .
Die WriteFileEx-Funktion schlägt möglicherweise fehl, wenn zu viele ausstehende asynchrone E/A-Anforderungen vorhanden sind. Im Falle eines solchen Fehlers kann GetLastError oder ERROR_NOT_ENOUGH_MEMORY
zurückgebenERROR_INVALID_USER_BUFFER
.
Verwenden Sie eine der folgenden Optionen, um alle ausstehenden asynchronen E/A-Vorgänge abzubrechen:
- CancelIo: Diese Funktion bricht nur Vorgänge ab, die vom aufrufenden Thread für das angegebene Dateihandle ausgegeben wurden.
- CancelIoEx: Diese Funktion bricht alle Vorgänge ab, die von den Threads für das angegebene Dateihandle ausgegeben werden.
Verwenden Sie CancelSynchronousIo, um ausstehende synchrone E/A-Vorgänge abzubrechen.
E/A-Vorgänge, die mit dem fehler ERROR_OPERATION_ABORTED abgebrochen werden.
Wenn ein Teil der durch hFile angegebenen Datei von einem anderen Prozess gesperrt wird und der angegebene Schreibvorgang den gesperrten Teil überlappt, schlägt WriteFileEx fehl.
Beim Schreiben in eine Datei wird der Zeitpunkt des letzten Schreibvorgangs erst vollständig aktualisiert, wenn alle zum Schreiben verwendeten Handles geschlossen wurden. Schließen Sie daher das Dateihandle unmittelbar nach dem Schreiben in die Datei, um eine genaue letzte Schreibzeit sicherzustellen.
Der Zugriff auf den Ausgabepuffer, während ein Schreibvorgang den Puffer verwendet, kann zu einer Beschädigung der aus diesem Puffer geschriebenen Daten führen. Anwendungen dürfen den Ausgabepuffer, den ein Schreibvorgang verwendet, nicht in schreiben, neu zuweisen oder freigeben, bis der Schreibvorgang abgeschlossen ist.
Beachten Sie, dass die Zeitstempel für eine Remotedatei möglicherweise nicht ordnungsgemäß aktualisiert werden. Um konsistente Ergebnisse zu gewährleisten, verwenden Sie ungepufferte E/A-Vorgänge.
Das System interpretiert null bytes to write so, dass ein NULL-Schreibvorgang angegeben wird, und WriteFile schneidet die Datei nicht ab oder erweitert sie nicht. Verwenden Sie zum Abschneiden oder Erweitern einer Datei die SetEndOfFile-Funktion .
Eine Anwendung verwendet die Funktionen WaitForSingleObjectEx, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsEx, SignalObjectAndWait und SleepEx , um einen warnbaren Wartezustand zu erhalten. Weitere Informationen zu warnbaren Wartezuständen und überlappenden E/A-Vorgängen finden Sie unter Informationen zur Synchronisierung.
Wenn Sie direkt auf ein Volume schreiben, das über ein eingebundenes Dateisystem verfügt, müssen Sie zunächst exklusiven Zugriff auf das Volume erhalten. Andernfalls besteht das Risiko einer Datenbeschädigung oder Systeminstabilität, da die Schreibvorgänge Ihrer Anwendung mit anderen Änderungen aus dem Dateisystem in Konflikt stehen und den Inhalt des Volumes in einem inkonsistenten Zustand belassen können. Um diese Probleme zu vermeiden, wurden die folgenden Änderungen in Windows Vista und höher vorgenommen:
- Ein Schreibvorgang auf ein Volumehandle ist erfolgreich, wenn das Volume kein eingebundenes Dateisystem aufweist oder eine der folgenden Bedingungen zutrifft:
- Die Sektoren, in die geschrieben werden soll, sind Startsektoren.
- Die Sektoren, die geschrieben werden sollen, um sich außerhalb des Dateisystembereichs zu befinden.
- Sie haben die Bereitstellung des Volumes mithilfe von FSCTL_LOCK_VOLUME oder FSCTL_DISMOUNT_VOLUME explizit gesperrt oder aufgehoben.
- Das Volume verfügt über kein tatsächliches Dateisystem. (Mit anderen Worten, es ist ein RAW-Dateisystem eingebunden.)
- Ein Schreibvorgang auf ein Datenträgerhandle ist erfolgreich, wenn eine der folgenden Bedingungen zutrifft:
- Die Sektoren, in die geschrieben werden soll, liegen nicht in den Umfang eines Volumes.
- Die Sektoren, die geschrieben werden sollen, um in ein eingebundenes Volume zu fallen, Aber Sie haben die Bereitstellung des Volumes mithilfe von FSCTL_LOCK_VOLUME oder FSCTL_DISMOUNT_VOLUME explizit gesperrt oder aufgehoben.
- Die Zu schreibenden Sektoren gehören zu einem Volume, das außer RAW über kein eingebundenes Dateisystem verfügt.
Es gibt strenge Anforderungen für die erfolgreiche Arbeit mit Dateien, die mit CreateFile mithilfe von FILE_FLAG_NO_BUFFERING geöffnet wurden. Weitere Informationen finden Sie unter Dateipufferung.
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 |
Transaktionierte Vorgänge
Ist an das Dateihandle eine Transaktion gebunden, ist der Dateischreibvorgang transaktiv. Weitere Informationen finden Sie unter Informationen zu Transaktions-NTFS.
Beispiele
Ein Beispiel finden Sie unter Named Pipe Server Using Completion Routines.
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 |