In Windows, devo usare CreateFile o fopen, portabilità da parte?
-
27-09-2019 - |
Domanda
Quali sono le differenze, e in quali casi l'uno o l'altro sarebbe rivelarsi superiore in qualche modo?
Soluzione
Prima di tutto la funzione di fopen
può essere utilizzata solo per semplici operazioni portatili con file.
CreateFile
sull'altro lato può essere utilizzato non solo per le operazioni con i file, ma anche con le directory (con l'uso di opzioni corrispondenti), tubi e vari dispositivi di Windows.
CreateFile
ha un sacco di interruttori utili addizionali, come FILE_FLAG_NO_BUFFERING
, FILE_ATTRIBUTE_TEMPORARY
e FILE_FLAG_SEQUENTIAL_SCAN
, che può essere molto utile in diversi scenari.
È possibile utilizzare CreateFile
con un nome più che i caratteri MAX_PATH
. Può essere importante per alcune applicazioni server o quelli che devono essere in grado di aprire qualsiasi file (un programma antivirus o di un'applicazione di backup, per esempio). Ciò è reso possibile utilizzando la semantica dello spazio dei nomi, anche se questa modalità ha le sue preoccupazioni, come la capacità di creare una realtà ".."
file chiamato o L"\xfeff\x20\xd9ab"
(buona fortuna cercando di eliminare in un secondo momento).
È possibile utilizzare CreateFile
in diversi scenari di sicurezza. Intendo non solo l'uso di attributi di sicurezza. Se il processo corrente ha SE_BACKUP_NAME o SE_RESTORE_NAME privilegio (come amministratori in genere hanno) e attivare questo privilegio, si può usare CreateFile
per aprire qualsiasi tipo di file anche un file a cui si ha accesso attraverso descrittore di protezione.
Se desideri solo leggere il contenuto di un file, è possibile utilizzare CreateFile
, CreateFileMapping
e MapViewOfFile
per creare mapping dei file. Poi si può lavorare con un file come con un blocco di memoria, che può eventualmente aumentare la velocità dell'applicazione.
Esistono anche altri usi della funzione, che sono descritte in dettaglio in corrispondente articolo MSDN.
Quindi posso riassumere: solo se si dispone di un disco requisiti di portabilità o se avete bisogno di passare un FILE*
a qualche libreria esterna, quindi è necessario utilizzare fopen
. In tutti gli altri casi, ti consiglierei di utilizzare CreateFile
.
Per ottenere i migliori risultati, vorrei anche consigliare di imparare API di Windows specificamente, in quanto vi sono molte caratteristiche che si possono trovare un buon uso per.
AGGIORNAMENTO : non direttamente correlate alla tua domanda, ma vi consiglio anche di prendere uno sguardo al I / O transazionale funzioni che sono supportate a partire da Windows Vista. Utilizzando questa funzione, si può commettere una serie di operazioni con i file, directory o Registro di sistema come una transazione che non può essere interrotto. Si tratta di uno strumento molto potente e interessante. Se non si è pronti ora ad utilizzare le funzioni transazionali di I / O, si può iniziare con CreateFile
e la porta l'applicazione per I / O transazionale in seguito.
Altri suggerimenti
Che in realtà dipende da che tipo di programma che si sta scrivendo. Se si suppone che sia portatile, fopen
renderà la vita più facile. fopen
chiamerà CreateFile
"dietro le quinte".
Alcune opzioni più avanzate (controllo della cache, il controllo di accesso ai file, ecc) sono disponibili solo se si utilizza l'API Win32 (che dipendono dal file handle Win32, in contrasto con il puntatore FILE
in stdio), quindi se siete scrivendo una pura applicazione Win32, si consiglia di utilizzare CreateFile.
CreateFile consente di
- Apri file di I / O asincrono
- Passo suggerimenti di ottimizzazione come FILE_FLAG_SEQUENTIAL_SCAN
- Set di sicurezza e di ereditare le impostazioni senza problemi di threading
Essi non restituiscono lo stesso tipo di impugnatura, con fopen / oggetto file è possibile chiamare altre funzioni di runtime, come fputs (così come convertirlo in un file handle "nativo")
Quando possibile, preferire oggetto wrapper oriented che il supporto Raii, come oggetti fstream o file di spinta IO.
Si dovrebbe, ovviamente, la cura circa la modalità di condivisione, in modo da fopen () e STL sono insufficienti.