2010-08-18 11 views
5

È possibile aggiornare solo una parte di un file in C++?Aggiornare solo una parte di un file binario con C++

Esempio:

vecchio file A: 'A''A''A''B''B''C''C''C'
File Nuovo A: ' A''A''A' 'X''X' 'C''C''C'

come i file reali non sono così piccolo come questi esempi, e so esattamente cosa è cambiato (offset e writeLenght per il contenuto modificato) sarebbe bello poter aprire un file, impostare lo stream nella giusta posizione, scrivere le informazioni e chiudere di nuovo il file .... ma questo porterà a un file simile al seguente:

File aggiornato: '0''0''0''X''X''C''C' ' C'

questo è il codice che ho usato:

void update file(list<unsigned char> content, int offset){ 

fs::basic_ofstream<char> fileStream(path , ios::out | ios::binary);  
list< unsigned char >::const_iterator contentIter = content.begin(); 
// begin write operation at the offset 
advance(contentIter , offset); 
fileStream.seekp(offset); 
while(contentIter != content.end()){ 
    unsigned char value = (char)*contentIter; 
    fileStream.put(value); 
    ++contentIter;   
} 
fileStream.close(); 

c'è un modo per fare questo, o ha l'intero file da riscrivere ogni volta che cambia?

Grazie

risposta

3

Ok mappato, grazie:
Ecco un pezzo di lavoro del codice nel caso qualcuno incontra la stessa domanda.

void update file(list<unsigned char> content, int offset, int writeLength){ 

fs::basic_fstream<char> fileStream(path , ios::out | ios::in | ios::binary);  
list< unsigned char >::const_iterator contentIter = content.begin(); 
// begin write operation at the offset 
advance(contentIter , offset); 
// set the Stream to the offset position 
fileStream.seekp(offset); 
while(contentIter != content.end() && writeLength != 0){ 
    unsigned char value = (char)*contentIter; 
    fileStream.put(value); 
    ++contentIter; 
    --writeLength;   
} 
fileStream.close(); 
} 

Si dovrebbe verificare la presenza di errori o dire il flusso di lanciare eccezioni quando si utilizza questo codice ....

7

Hai praticamente l'idea giusta. La cosa principale che devi modificare è utilizzare fstream anziché ofstream e utilizzare ios::in | ios::out quando lo apri (supponendo che fs::basic_ofstream risolva in qualche modo a std::basic_ofstream). Quando apri con solo , il contenuto del file esistente viene distrutto.

Modifica: A proposito, ho difficoltà a immaginare una situazione in cui l'utilizzo di std::list<char> è una buona idea. Su una macchina tipica con puntatori a 32 bit e 8 bit char s, stai cercando di utilizzare 8 volte tanto spazio per i puntatori quanto lo sei per i dati che stai tentando di memorizzare e il tuo accesso ai dati che hai il negozio è generalmente piuttosto lento.

+0

Grazie per la risposta. Questo è esattamente quello che stavo cercando. Per quanto riguarda i caratteri: Sto scrivendo un programma di stress test per schede di memoria flash. Devo essere in grado di generare schemi in cui ogni byte ha un valore definito. Questi schemi sono memorizzati internamente e scritti in un file. Di tanto in tanto li rileggo e li confronta con i modelli memorizzati. Sono quindi in grado di dire la posizione esatta dell'errore e controllare se è riproducibile. – zitroneneis

3

Non come C++ 'ish, ma il modo più ovvio per farlo è con la memoria i file

Problemi correlati