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, un socket, una risorsa di comunicazione, un file 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 e sicurezza dei 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 dalla funzione socket o 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.

Il valore zero specifica un'operazione di scrittura Null. Il comportamento di un'operazione di scrittura Null dipende dal file system o dalla tecnologia di comunicazione sottostante.

Windows Server 2003 e Windows XP: Le operazioni di scrittura tramite pipe in una rete sono limitate per ogni scrittura. La quantità varia in base alla 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 il controllo degli errori o del lavoro. 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; in caso contrario, 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 e OffsetHigh vengono ignorati.

Per scrivere alla fine del file, specificare sia i membri Offset che OffsetHigh della struttura OVERLAPPED come 0xFFFFFFFF. Ciò equivale funzionalmente alla chiamata precedente della funzione CreateFile per aprire hFile usando FILE_APPEND_DATA l'accesso.

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 .

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

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.
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 eseguite 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 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 da 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'ora dell'ultima 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 in, riallocare o liberare il buffer di output usato da un'operazione di scrittura fino al completamento dell'operazione di scrittura. Ciò può risultare 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 filee 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 non memorizzato nel buffer.

Il sistema interpreta zero byte da 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 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 è determinato dal timeout di comunicazione corrente impostato e recuperato usando le funzioni 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 settore singolo è atomica, non è garantito che una scrittura a più settori 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 garantire che un'intera scrittura multiseme sia scritta nel disco senza potenziali ritardi nella memorizzazione nella cache.

Se si scrive direttamente in un volume con un file system montato, è innanzitutto 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 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:

  • Un handle di 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 d'avvio.
    • I settori da scrivere in risiedono 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 alcun file system effettivo. In altre parole, ha un file system RAW montato.
  • Se una delle condizioni seguenti è vera, una scrittura su un handle del disco avrà esito positivo:
    • I settori da scrivere in non rientrano nelle dimensioni di un volume.
    • I settori da scrivere in un volume montato, ma il volume è stato bloccato o smontato in modo esplicito utilizzando FSCTL_LOCK_VOLUME o FSCTL_DISMOUNT_VOLUME.
    • I settori da scrivere per rientrare in un volume senza 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 dei file.

Se hFile è stato aperto con FILE_FLAG_OVERLAPPED, sono effettive le condizioni seguenti:

  • Il parametro lpOverlapped deve puntare a una struttura 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 Supportato
Protocollo SMB (Server Message Block) 3.0
Failover trasparente SMB 3.0 (TFO)
SMB 3.0 con condivisioni file con scalabilità orizzontale (SO)
File system del volume condiviso del cluster (CsvFS)
File system resiliente (ReFS)
 

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.
Nota Se un file o un dispositivo viene aperto per le operazioni di I/O asincrone, le chiamate successive a funzioni come WriteFile usando tale handle restituiscono in genere immediatamente, ma possono anche comportarsi in modo sincrono rispetto all'esecuzione bloccata. Per altre informazioni, vedere http://support.microsoft.com/kb/156932.
 
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 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).
Considerazioni sull'uso degli handle di file sincroni:
  • Se lpOverlapped è NULL, l'operazione di scrittura inizia alla posizione del file corrente e WriteFile non restituisce finché l'operazione non viene completata 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.
Per altre informazioni, vedere CreateFile e Synchronous and Asincron I/O.

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

Vedere anche

CancelIo

CancelIoEx

CancelSynchronousIo

CreateFile

CreateFileTransacted

Funzioni di gestione file

Getlasterror

GetOverlappedResult

GetQueuedCompletionStatus

ReadFile

SetEndOfFile

WriteFileEx