2012-10-17 16 views
12

Eventuali duplicati:
C++ Filehandling: Difference between ios:app and ios:ate?Differenza tra ios :: app e iOS :: mangiato

Qual è la differenza tra questi due modi di file di apertura?

ios: ate imposta la posizione del puntatore get/put alla fine del file => lettura/scrittura inizierà dalla fine, ma in che modo è diverso da ios :: app, che apre nuovamente un file in modalità append ... ma quando ho creato un ofstream e l'ho aperto in ios: modalità app, il puntatore del flusso messo punta ancora all'inizio, come funziona allora l'aggiunta?

Inoltre, ho capito che ifstream, ofstream e fstream sono classi di alto livello per gestire il buffer del flusso sottostante. Quindi vuol dire che anche in ios: modalità app posso leggere i dati da un file?

+1

In pratica, l''app' cerca sempre fino alla fine prima di scrivere qualsiasi cosa, mentre 'ate' ti consente di cercare dopo l'apertura e di mantenerla lì. Vedi [questa domanda] (http://stackoverflow.com/questions/10359702/c-filehandling-difference-between-iosapp-and-iosate). – chris

risposta

23

app deriva da "append" - l'output verrà aggiunto (aggiunto) alla fine del file. In altre parole, non puoi scrivere altrove nel file ma alla fine

ate come forma 'alla fine' - imposta la posizione del flusso alla fine del file quando lo apri ma sei libero di spostarlo (cerca) e scrivi ovunque ti piaccia.

+0

Il fatto che 'mangiato 'non impedisca il troncamento lo rende praticamente inutile. Il fatto che 'app' possa aggiungere record parziali alla fine in momenti non specificati (a causa del buffering) lo rende praticamente inutile. –

+0

@James: in che modo 'app' /' ate' è diverso in questo rispetto dalle scritture alla fine dei file che * non sono * stati aperti con tali flag? Pensavo che fosse solo inteso come una comodità per salvare una ricerca. Non mi ero reso conto che qualcuno si aspettasse che rispolverasse il flusso per loro, o comunque garantisse l'integrità dei file. –

+0

@SteveJessop 'app' esegue il mapping a' "a" 'in' fopen'. Lo standard C non richiede atomicità, perché non tutti i sistemi possono supportarlo, ma lo _intent_ originale di "" a "' era per l'implementazione per utilizzare il flag 'O_APPEND' quando si apre il file. Il che fa sì che la ricerca atomica finisca prima di ogni scrittura. La differenza è visibile se altri processi stanno scrivendo sul file. Quando un altro processo scrive sul file, la tua posizione nel file non avanza, e la tua prossima scrittura sovrascriverà qualsiasi cosa abbia scritto. Con 'app', la tua prossima scrittura verrà aggiunta, indipendentemente (e non c'è razza). –

8

Se si guarda ad es. this reference, si vedrà:

app  seek to the end of stream before each write 

e

ate  seek to the end of stream immediately after open 

Questo significa che ios::app scrive solo alla fine, ma che ios::ate legge e scrive alla fine di default. Tuttavia, con ios::ate puoi cercare liberamente nel file, ma con ios::app avrai sempre scrivendo alla fine, indipendentemente dalla posizione impostata per il puntatore di scrittura.

10

ate posiziona semplicemente alla fine del file dopo l'apertura e nient'altro. Non è molto utile su un ofstream, almeno senza altri flag, poiché il file sarà stato troncato comunque, quindi l'inizio è la fine. (Per evitare il troncamento, e di essere ancora in grado di scrivere in qualsiasi parte del file, è necessario o in ios::in così, anche se non avete intenzione di leggere.)

app impedisce il troncamento di un file esistente, e fa sì che ogni scrittura vada alla fine del file. Atomicamente, se possibile; se altri processi scrivono sullo stesso file, la tua scrittura dovrebbe ancora andare alla fine. Si noti tuttavia che questo si riferisce alla scrittura del livello di sistema effettivo. Se, tuttavia, si scrivono righe inferiori alla dimensione del buffer e si termina ogni riga con std::endl, è possibile contare su ogni riga aggiunta in modo atomico, indipendentemente da ciò che altri processi potrebbero fare con il file. Per essere efficace, probabilmente si desidera utilizzare pubsetbuf su filebuf per garantire una dimensione minima del buffer.

In pratica, non credo di aver mai usato nessuno di loro, né trovato di alcun uso.I problemi di buffering con app, in particolare, mi hanno portato in genere a scrivere il mio streambuf, con buffering concettualmente illimitato (uno std::vector<char> come buffer), che apre il file di sistema sottostante con l'equivalente di app, ma garantisce solo la scrittura su di esso quando esplicitamente svuotato (come con `std :: endl).

Problemi correlati