Обновите только часть двоичного файла с помощью C ++ - PullRequest
5 голосов
/ 18 августа 2010

Возможно ли обновить только часть файла в c ++?

Пример:

Старый файл A: 'A''A''A''B''B''C''C''C'
Новый файл A: ' A''A''A '' X''X '' C''C''C '

поскольку реальные файлы не такие крошечные, как в этих примерах, и я точно знаю, что изменилось (offset и writeLenght для измененного содержимого), было бы здорово иметь возможность открыть файл, установить поток в правильное положение, запишите информацию и закройте файл снова .... но это приведет к тому, что файл будет выглядеть следующим образом:

Обновленный файл: '0''0''0''X' 'X''C''C''C '

Это код, который я использовал:

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();

Есть ли способ сделать это, или весь файлпереписывать каждый раз, когда он меняется?

Спасибо

Ответы [ 3 ]

7 голосов
/ 18 августа 2010

У вас есть почти правильная идея. Главное, что вам нужно изменить, это использовать fstream вместо ofstream и использовать ios::in | ios::out при его открытии (предполагая, что fs::basic_ofstream каким-то образом разрешает std::basic_ofstream). Когда вы открываете только с помощью ios::out, содержимое существующего файла уничтожается.

Редактировать: Кстати, мне трудно представить себе ситуацию, когда использование std::list<char> является хорошей идеей. На обычной машине с 32-разрядными указателями и 8-разрядными char с вы рассматриваете использование в 8 раз большего пространства для указателей, чем для данных, которые вы пытаетесь сохранить, и ваш доступ к данные, которые вы храните, обычно тоже довольно медленные.

4 голосов
/ 19 августа 2010

Хорошо, спасибо:
Вот рабочий фрагмент кода на случай, если кто-то столкнется с тем же вопросом.

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(); 
}

Нужно проверять ошибки или указывать потоку генерировать исключения при использовании этого кода ....

4 голосов
/ 18 августа 2010

Не так, как в c ++, но очевидный способ сделать это с помощью файлов с отображенной памятью

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...