Condividi tramite


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 deve essere stato creato con l'accesso in scrittura. Per altre informazioni, vedere diritti di accesso generico e diritti di accesso e sicurezza dei file.

Per le operazioni di scrittura asincrone, hFile può essere qualsiasi handle aperto con la funzione CreateFile utilizzando il flag FILE_FLAG_OVERLAPPED o un handle socket restituito dal socket o accettare funzione.

[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 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 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 e i membri OffsetHigh della struttura OVERLAPPED. Per un hFile che non supporta gli offset di byte, i offset offset e OffsetHigh vengono ignorati.

Per scrivere alla fine del file, specificare sia il Offset che i membri offsetHighHigh della struttura OVERLAPPED come 0xFFFFFFFF. Ciò equivale funzionalmente alla chiamata precedente 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 estese sull'errore, chiamare la funzione GetLastError .

Nota Il codice GetLastErrorERROR_IO_PENDING non è un errore; indica che l'operazione di scrittura è in attesa di completamento in modo asincrono. Per altre informazioni, vedere Osservazioni.
 

Osservazioni

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 viene eseguita in modo asincrono.
  • Si verifica un errore.
La funzione WriteFile potrebbe non riuscire con ERROR_INVALID_USER_BUFFER o ERROR_NOT_ENOUGH_MEMORY ogni volta che sono presenti troppe richieste di I/O asincrone in sospeso.

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.
Usare la funzione di
CancelSynchronousIo per annullare le operazioni di I/O sincrone in sospeso.

Le operazioni di I/O annullate vengono 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 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 WriteFile viene determinato dal timeout di comunicazione corrente impostato e recuperato usando le funzioni di SetCommTimeouts e GetCommTimeouts. I risultati imprevedibili possono verificarsi se non si impostano i valori di timeout. Per altre informazioni sui timeout delle comunicazioni, vedere COMMTIMEOUTS.

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.
Esistono requisiti rigorosi per l'uso corretto dei file aperti con CreateFile usando FILE_FLAG_NO_BUFFERING. Per informazioni dettagliate, vedere buffering di file.

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.
In Windows Server 2012 questa funzione è supportata dalle tecnologie seguenti.
Tecnologia Sostenuto
Protocollo SMB (Server Message Block) 3.0
SMB 3.0 Transparent Failover (TFO)
SMB 3.0 con condivisioni file con scalabilità orizzontale (SO)
Cluster Shared Volume File System (CsvFS)
Resilient File System (ReFS)
 

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
OVERLAPPED sono leggermente diverse per ognuna, come indicato in precedenza.
Nota Se un file o un dispositivo viene aperto per le operazioni di I/O asincrone, le chiamate successive a funzioni come WriteFile utilizzando tale handle in genere restituiscono immediatamente, ma possono anche comportarsi in modo sincrono rispetto all'esecuzione bloccata. Per altre informazioni, vedere I/O del disco asincrono viene visualizzato come sincrono in Windows.
 
Considerazioni sull'uso degli handle di file asincroni:
  • 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).
Considerazioni sull'uso degli handle di file sincroni:
  • 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 OVERLAPPED e 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.
Per altre informazioni, vedere CreateFile e I/O sincroni e asincroni.

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 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 del 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 *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
size è la dimensione del blocco di dati originale che si desidera scrivere nel file. Per altre regole relative all'I/O dei file non memorizzati nel buffering dei file, vedere buffering di 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;
}

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

Vedere anche

CancelIo

CancelIoEx

CancelSynchronousIo

CreateFile

CreateFileTransacted

funzioni di gestione file

GetLastError

GetOverlappedResult

GetQueuedCompletionStatus

ReadFile

SetEndOfFile

WriteFileEx