Funzione WriteFile (fileapi.h)
Scrive i dati nel dispositivo di input/output (I/O) specificato.
Questa funzione è progettata sia per l'operazione sincrona che asincrona. Per una funzione simile progettata esclusivamente per l'operazione asincrona, vedere WriteFileEx.
Sintassi
BOOL WriteFile(
[in] HANDLE hFile,
[in] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[out, optional] LPDWORD lpNumberOfBytesWritten,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
Parametri
[in] hFile
Handle per il dispositivo file o I/O, ad esempio un file, un flusso di file, un disco fisico, un volume, un buffer della console, un'unità nastro, un socket, una risorsa di comunicazione, una mailslot o una pipe.
Il parametro hFile deve essere stato creato con l'accesso in scrittura. Per altre informazioni, vedere Diritti di accesso generico e diritti di accesso ai file.
Per le operazioni di scrittura asincrone, hFile può essere qualsiasi handle aperto con la funzione CreateFile usando il flag FILE_FLAG_OVERLAPPED o un handle socket restituito dal socket o dalla funzione accept .
[in] lpBuffer
Puntatore al buffer contenente i dati da scrivere nel file o nel dispositivo.
Questo buffer deve rimanere valido per la durata dell'operazione di scrittura. Il chiamante non deve usare questo buffer fino al completamento dell'operazione di scrittura.
[in] nNumberOfBytesToWrite
Numero di byte da scrivere nel file o nel dispositivo.
Un valore pari a zero specifica un'operazione di scrittura Null. Il comportamento di un'operazione di scrittura Null dipende dalla tecnologia di file system o comunicazione sottostante.
Windows Server 2003 e Windows XP: Le operazioni di scrittura della pipe in una rete sono limitate per ogni scrittura. L'importo varia per piattaforma. Per le piattaforme x86 è 63,97 MB. Per le piattaforme x64 è 31,97 MB. Per Itanium è 63,95 MB. Per altre informazioni sulle pipe, vedere la sezione Osservazioni.
[out, optional] lpNumberOfBytesWritten
Puntatore alla variabile che riceve il numero di byte scritti quando si usa un parametro hFile sincrono. WriteFile imposta questo valore su zero prima di eseguire qualsiasi controllo di lavoro o errore. Usare NULL per questo parametro se si tratta di un'operazione asincrona per evitare risultati potenzialmente errati.
Questo parametro può essere NULL solo quando il parametro lpOverlapped non è NULL.
Windows 7: Questo parametro non può essere NULL.
Per altre informazioni, vedere la sezione Osservazioni.
[in, out, optional] lpOverlapped
È necessario un puntatore a una struttura OVERLAPPED se il parametro hFile è stato aperto con FILE_FLAG_OVERLAPPED, altrimenti questo parametro può essere NULL.
Per un hFile che supporta gli offset di byte, se si usa questo parametro è necessario specificare un offset di byte in corrispondenza del quale iniziare a scrivere nel file o nel dispositivo. Questo offset viene specificato impostando i membri Offset e OffsetHigh della struttura OVERLAPPED. Per un hFile che non supporta gli offset di byte, offset eOffsetHigh vengono ignorati.
Per scrivere alla fine del file, specificare sia i membri Offset che OffsetHigh della struttura OVERLAPPED come 0xFFFFFFFF. Ciò equivale in precedenza alla chiamata della funzione CreateFile per aprire hFile usando l'accesso FILE_APPEND_DATA .
Per altre informazioni sulle diverse combinazioni di lpOverlapped e FILE_FLAG_OVERLAPPED, vedere la sezione Osservazioni e la sezione Sincronizzazione e posizione file .
Valore restituito
Se la funzione ha esito positivo, il valore restituito è diverso da zero (TRUE).
Se la funzione ha esito negativo o viene completata in modo asincrono, il valore restituito è zero (FALSE). Per ottenere informazioni sull'errore estese, chiamare la funzione GetLastError .
Commenti
La funzione WriteFile restituisce quando si verifica una delle condizioni seguenti:
- Il numero di byte richiesti viene scritto.
- Un'operazione di lettura rilascia spazio buffer sulla fine di lettura della pipe (se la scrittura è stata bloccata). Per altre informazioni, vedere la sezione Pipe .
- Viene usato un handle asincrono e la scrittura si verifica in modo asincrono.
- Si verifica un errore.
Per annullare tutte le operazioni di I/O in sospeso, usare:
- CancelIo: questa funzione annulla solo le operazioni rilasciate dal thread chiamante per l'handle di file specificato.
- CancelIoEx: questa funzione annulla tutte le operazioni rilasciate dai thread per l'handle di file specificato.
Operazioni di I/O annullate completate con l'errore ERROR_OPERATION_ABORTED.
La funzione WriteFile potrebbe non riuscire con ERROR_NOT_ENOUGH_QUOTA, il che significa che il buffer del processo chiamante non può essere bloccato a pagina. Per altre informazioni, vedere SetProcessWorkingSetSize.
Se parte del file è bloccata da un altro processo e l'operazione di scrittura si sovrappone alla parte bloccata, WriteFile ha esito negativo.
Quando si scrive in un file, l'ultima volta di scrittura non viene aggiornata completamente fino a quando non sono stati chiusi tutti gli handle usati per la scrittura. Pertanto, per garantire un'ora di scrittura accurata, chiudere l'handle di file immediatamente dopo la scrittura nel file.
L'accesso al buffer di output mentre un'operazione di scrittura usa il buffer può causare il danneggiamento dei dati scritti da tale buffer. Le applicazioni non devono scrivere in, riallocare o liberare il buffer di output usato da un'operazione di scrittura fino al completamento dell'operazione di scrittura. Questo può essere particolarmente problematico quando si usa un handle di file asincrono. Altre informazioni relative agli handle di file sincroni rispetto ai handle di file asincroni sono disponibili più avanti nella sezione Sincronizzazione e posizione file eI/O sincrona.
Si noti che i timestamp potrebbero non essere aggiornati correttamente per un file remoto. Per garantire risultati coerenti, usare I/O non memorizzati.
Il sistema interpreta zero byte per scrivere come specificare un'operazione di scrittura Null e WriteFile non tronca o estende il file. Per troncare o estendere un file, usare la funzione SetEndOfFile .
I caratteri possono essere scritti nel buffer dello schermo usando WriteFile con un handle per l'output della console. Il comportamento esatto della funzione è determinato dalla modalità console. I dati sono scritti nella posizione del cursore corrente. La posizione del cursore viene aggiornata dopo l'operazione di scrittura. Per altre informazioni sugli handle della console, vedere CreateFile.
Quando si scrive in un dispositivo di comunicazione, il comportamento di WriteFile viene determinato dal timeout di comunicazione corrente come impostato e recuperato usando le funzioni SetCommTimeouts e GetCommTimeouts. I risultati imprevedibili possono verificarsi se non è possibile impostare i valori di timeout. Per altre informazioni sui timeout delle comunicazioni, vedere COMMTIMEOUTS.
Anche se una scrittura a singolo settore è atomica, una scrittura a più settori non è garantita a meno che non si usi una transazione , ovvero l'handle creato è un handle transazionale, ad esempio un handle creato usando CreateFileTransacted. Le scritture multi-settore memorizzate nella cache potrebbero non essere sempre scritte sul disco immediatamente; specificare pertanto FILE_FLAG_WRITE_THROUGH in CreateFile per garantire che un intero write multi-settore venga scritto nel disco senza potenziali ritardi di memorizzazione nella cache.
Se si scrive direttamente in un volume con un file system montato, è prima necessario ottenere l'accesso esclusivo al volume. In caso contrario, si rischia di causare il danneggiamento dei dati o l'instabilità del sistema, perché le scritture dell'applicazione potrebbero conflitto con altre modifiche provenienti dal file system e lasciare il contenuto del volume in uno stato incoerente. Per evitare questi problemi, sono state apportate le modifiche seguenti in Windows Vista e versioni successive:
- Una scrittura in un handle di volume avrà esito positivo se il volume non ha un file system montato o se una delle condizioni seguenti è true:
- I settori da scrivere in sono settori di avvio.
- I settori da scrivere per risiedere all'esterno dello spazio del file system.
- Il volume è stato bloccato o smontato in modo esplicito usando FSCTL_LOCK_VOLUME o FSCTL_DISMOUNT_VOLUME.
- Il volume non ha file system effettivo. In altre parole, ha un file system RAW montato.
- Una scrittura in un handle di disco avrà esito positivo se una delle condizioni seguenti è true:
- I settori da scrivere in modo da non rientrare nelle estensioni di un volume.
- I settori da scrivere in un volume montato, ma sono stati bloccati o smontati in modo esplicito il volume usando FSCTL_LOCK_VOLUME o FSCTL_DISMOUNT_VOLUME.
- I settori da scrivere in modo da rientrare in un volume che non dispone di file system montato diverso da RAW.
Se hFile è stato aperto con FILE_FLAG_OVERLAPPED, le condizioni seguenti sono effettive:
- Il parametro lpOverlapped deve puntare a una struttura OVERLAPPED valida e univoca, altrimenti la funzione può segnalare in modo errato che l'operazione di scrittura sia stata completata.
- Il parametro lpNumberOfBytesWritten deve essere impostato su NULL. Per ottenere il numero di byte scritti, usare la funzione GetOverlappedResult . Se il parametro hFile è associato a una porta di completamento di I/O, è anche possibile ottenere il numero di byte scritti chiamando la funzione GetQueuedCompletionStatus .
Tecnologia | Supportato |
---|---|
Protocollo SMB (Server Message Block) 3.0 | Sì |
Failover trasparente SMB 3.0 (TFO) | Sì |
SMB 3.0 con condivisioni file con scalabilità orizzontale (SO) | Sì |
File system del volume condiviso del cluster (CsvFS) | Sì |
File system resiliente (ReFS) | Sì |
Sincronizzazione e posizione file
Se hFile viene aperto con FILE_FLAG_OVERLAPPED, è un handle di file asincrono; altrimenti è sincrona. Le regole per l'uso della struttura OVERLAPPED sono leggermente diverse per ognuna, come indicato in precedenza.- WriteFile può restituire prima del completamento dell'operazione di scrittura. In questo scenario WriteFile restituisce FALSE e la funzione GetLastError restituisce ERROR_IO_PENDING, che consente al processo chiamante di continuare mentre il sistema completa l'operazione di scrittura.
- Il parametro lpOverlapped non deve essere NULL e deve essere usato con i fatti seguenti:
- Sebbene l'evento specificato nella struttura OVERLAPPED sia impostato e reimpostato automaticamente dal sistema, l'offset specificato nella struttura OVERLAPPED non viene aggiornato automaticamente.
- WriteFile reimposta l'evento in uno stato non firmato quando inizia l'operazione di I/O.
- L'evento specificato nella struttura OVERLAPPED è impostato su uno stato segnalato al termine dell'operazione di scrittura; fino a quel momento, l'operazione di scrittura viene considerata in sospeso.
- Poiché l'operazione di scrittura inizia all'offset specificato nella struttura OVERLAPPED e WriteFile può restituire prima che l'operazione di scrittura a livello di sistema venga completata (scrittura in sospeso), né l'offset né qualsiasi altra parte della struttura deve essere modificata, liberata o riutilizzata dall'applicazione fino a quando l'evento non viene segnalato (ovvero la scrittura viene completata).
- Se lpOverlapped è NULL, l'operazione di scrittura inizia alla posizione del file corrente e WriteFile non restituisce fino al completamento dell'operazione e il sistema aggiorna il puntatore di file prima che WriteFile restituisca.
- Se lpOverlapped non è NULL, l'operazione di scrittura inizia all'offset specificato nella struttura OVERLAPPED e WriteFile non restituisce fino al completamento dell'operazione di scrittura. Il sistema aggiorna i campi OVERLAPPED Internal e InternalHigh e il puntatore al file prima che WriteFile restituisca.
Tubi
Se viene usata una pipe anonima e l'handle di lettura è stato chiuso, quando WriteFile tenta di scrivere usando l'handle di scrittura corrispondente della pipe, la funzione restituisce FALSE e GetLastError restituisce ERROR_BROKEN_PIPE.Se il buffer della pipe è pieno quando un'applicazione usa la funzione WriteFile per scrivere in una pipe, l'operazione di scrittura potrebbe non terminare immediatamente. L'operazione di scrittura verrà completata quando un'operazione di lettura (usando la funzione ReadFile ) rende disponibile più spazio buffer di sistema per la pipe.
Quando si scrive in un handle pipe in modalità byte senza blocco con spazio buffer insufficiente, WriteFile restituisce TRUE con *lpNumberOfBytes Write<nNumberOfBytesToWrite.
Per altre informazioni sulle pipe, vedere Pipe.
Operazioni transazionate
Se è presente una transazione associata all'handle di file, viene eseguita la transazione di scrittura del file. Per altre informazioni, vedere Informazioni su NTFS transazionale.Esempio
Per alcuni esempi, vedere Creazione e uso di un file temporaneo e apertura di un file per la lettura o la scrittura.
Nell'esempio C++ seguente viene illustrato come allineare i settori per le scritture di file non memorizzate. La variabile Size è la dimensione del blocco di dati originale che si è interessati a scrivere nel file. Per altre regole relative all'I/O dei file non memorizzati, vedere Buffering file.#include <windows.h>
#define ROUND_UP_SIZE(Value,Pow2) ((SIZE_T) ((((ULONG)(Value)) + (Pow2) - 1) & (~(((LONG)(Pow2)) - 1))))
#define ROUND_UP_PTR(Ptr,Pow2) ((void *) ((((ULONG_PTR)(Ptr)) + (Pow2) - 1) & (~(((LONG_PTR)(Pow2)) - 1))))
int main()
{
// Sample data
unsigned long bytesPerSector = 65536; // obtained from the GetFreeDiskSpace function.
unsigned long size = 15536; // Buffer size of your data to write.
// Ensure you have one more sector than Size would require.
size_t sizeNeeded = bytesPerSector + ROUND_UP_SIZE(size, bytesPerSector);
// Replace this statement with any allocation routine.
auto buffer = new uint8_t[SizeNeeded];
// Actual alignment happens here.
auto bufferAligned = ROUND_UP_PTR(buffer, bytesPerSector);
// ... Add code using bufferAligned here.
// Replace with corresponding free routine.
delete buffer;
}
Requisiti
Client minimo supportato | Windows XP [app desktop | App UWP] |
Server minimo supportato | Windows Server 2003 [app desktop | App UWP] |
Piattaforma di destinazione | Windows |
Intestazione | fileapi.h (includere Windows.h) |
Libreria | Kernel32.lib |
DLL | Kernel32.dll |