Funzione WriteFile (fileapi.h)
Scrive i dati nel file o nel dispositivo di input/output (I/O) specificato.
Questa funzione è progettata sia per l'operazione sincrona che per l'operazione 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 file o il dispositivo di I/O, ad esempio un file, un flusso di file, un disco fisico, un volume, un buffer della console, un'unità nastro, socket, risorsa di comunicazione, mailslot o pipe.
Il parametro hFile
Per le operazioni di scrittura asincrone,
[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.
Il valore zero specifica un'operazione di scrittura Null. Il comportamento di un'operazione di scrittura Null dipende dalla tecnologia di comunicazione o del file system sottostante.
Windows Server 2003 e Windows XP: le operazioni di scrittura pipe in una rete sono limitate per scrittura. La quantità 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 di
Per un hFile che supporta gli offset di byte, se si utilizza 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 il offset
Per scrivere alla fine del file, specificare sia il Offset
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 estese sull'errore, chiamare la funzione GetLastError
Osservazioni
La funzione WriteFile
- 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 viene eseguita in modo asincrono.
- Si verifica un errore.
Per annullare tutte le operazioni di I/O asincrone 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 eseguite dai thread per l'handle di file specificato.
Le operazioni di I/O annullate vengono completate con l'errore ERROR_OPERATION_ABORTED.
La funzione WriteFile
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 vengono chiusi tutti gli handle utilizzati per la scrittura. Pertanto, per garantire un'ora dell'ultima 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, riallocare o liberare il buffer di output usato da un'operazione di scrittura fino al completamento dell'operazione di scrittura. Ciò può essere particolarmente problematico quando si usa un handle di file asincrono. Altre informazioni relative agli handle di file sincroni e asincroni sono disponibili più avanti nella sezione sincronizzazione e posizione file e I/O sincrona e asincrona.
Si noti che i timestamp potrebbero non essere aggiornati correttamente per un file remoto. Per garantire risultati coerenti, usare l'I/O senza buffer.
Il sistema interpreta zero byte da scrivere come specifica 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 corrente del cursore. 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
Anche se una scrittura a singolo settore è atomica, non è garantito che una scrittura multiseme sia atomica, 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 assicurarsi che nel disco venga scritta un'intera scrittura multiseme senza potenziali ritardi nella 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 danneggiamento dei dati o instabilità del sistema, perché le scritture dell'applicazione potrebbero entrare in 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 su un handle di volume avrà esito positivo se il volume non dispone di un file system montato o se una delle condizioni seguenti è vera:
- I settori da scrivere in sono settori di avvio.
- I settori da scrivere in si trovano 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 un file system effettivo. In altre parole, ha un file system RAW montato.
- Una scrittura in un handle del disco avrà esito positivo se una delle condizioni seguenti è vera:
- I settori da scrivere in non rientrano negli extent di un volume.
- I settori da scrivere in rientrano in un volume montato, ma il volume è stato bloccato o smontato in modo esplicito usando FSCTL_LOCK_VOLUME o FSCTL_DISMOUNT_VOLUME.
- I settori da scrivere in modo da rientrare in un volume che non dispone di un file system montato diverso da RAW.
Se hFile è stato aperto con FILE_FLAG_OVERLAPPED, sono effettive le condizioni seguenti:
- Il parametro lpOverlapped
deve puntare a una struttura di OVERLAPPED valida e univoca. In caso contrario, la funzione può segnalare erroneamente che l'operazione di scrittura è 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 I/O, è anche possibile ottenere il numero di byte scritti chiamando la funzione GetQueuedCompletionStatus.
Tecnologia | Sostenuto |
---|---|
Protocollo SMB (Server Message Block) 3.0 | Sì |
SMB 3.0 Transparent Failover (TFO) | Sì |
SMB 3.0 con condivisioni file con scalabilità orizzontale (SO) | Sì |
Cluster Shared Volume File System (CsvFS) | Sì |
Resilient File System (ReFS) | Sì |
sincronizzazione e posizione dei file
Se hFile viene aperto con FILE_FLAG_OVERLAPPED, è un handle di file asincrono; in caso contrario, è sincrono. Le regole per l'uso della struttura- 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 tenendo presente quanto segue: - Anche se l'evento specificato nella struttura
OVERLAPPED viene impostato e reimpostato automaticamente dal sistema, l'offset specificato nella struttura OVERLAPPED non viene aggiornato automaticamente. - WriteFile reimposta l'evento su uno stato non firmato all'avvio dell'operazione di I/O.
- L'evento specificato nella struttura
OVERLAPPED viene 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 con l'offset specificato nella struttura
OVERLAPPED e WriteFile può restituire prima che l'operazione di scrittura a livello di sistema sia stata completata (scrittura in sospeso), né l'offset né qualsiasi altra parte della struttura deve essere modificato, liberato o riutilizzato dall'applicazione fino a quando l'evento non viene segnalato (ovvero, la scrittura viene completata).
- Anche se l'evento specificato nella struttura
- Se lpOverlapped è NULL, l'operazione di scrittura inizia con la posizione del file corrente e writeFile non restituisce finché l'operazione non viene completata e il sistema aggiorna il puntatore al file prima di WriteFile restituisce.
- Se
lpOverlapped non è null , l'operazione di scrittura inizia all'offset specificato nella struttura OVERLAPPEDe WriteFile non restituisce fino al completamento dell'operazione di scrittura. Il sistema aggiorna i campi OVERLAPPED Interno e InternoHigh e il puntatore al file prima di WriteFile restituisce.
pipe
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
Quando si scrive in un handle pipe in modalità byte senza blocco con spazio buffer insufficiente, WriteFile restituisce true con *lpNumberOfBytesWritten<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 About Transactional NTFS.Esempi
Per alcuni esempi, vedere Creazione e uso di un file temporaneo e apertura di un file per la lettura o la scrittura di.
Nell'esempio C++ seguente viene illustrato come allineare i settori per le scritture di file non memorizzate nel buffer. La variabile#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;
}
Fabbisogno
Requisito | Valore |
---|---|
client minimo supportato | Windows XP [app desktop | App UWP] |
server minimo supportato | Windows Server 2003 [app desktop | App UWP] |
piattaforma di destinazione | Finestre |
intestazione |
fileapi.h (include Windows.h) |
libreria |
Kernel32.lib |
dll | Kernel32.dll |