C ++, чтение и запись в двоичный файл одновременно - PullRequest
2 голосов
/ 23 февраля 2010

Я хотел знать, возможно ли прочитать байт из двоичного файла с помощью «fstream», а затем изменить этот байт и записать его обратно.Я попробовал этот код, но он не сработал, и ничего не происходит, но я уверен, что он правильно читает.

file.open(path, ios::in|ios::out|ios::binary|ios::ate);
file.seekg(0, ios::end);
int size=file.tellg();
file.seekg(0,ios::beg);
char buffer;    
for(int i=0;i<size;i++)
{
    file.read((char*)&buffer,sizeof(char));
    buffer=(buffer+7)%256;
    file.write((char*)&buffer, sizeof(char));
}

если я возьму указатель файла на один байт после прочтения следующим образом:

file.seekg(-1, ios::cur);

Заранее спасибо.

Ответы [ 4 ]

6 голосов
/ 23 февраля 2010

Да. Как вы предложили в вопросе, вам нужно отрегулировать положение указателя файла, используя seekg, если вы хотите перезаписать ранее прочитанные байты. После каждого чтения указатель файла будет располагаться после прочитанных байтов.

2 голосов
/ 23 февраля 2010

Вы должны переместить указатель назад на количество предыдущих прочитанных байтов; так и с символом -1.

file.seekg(-1, std::ios::cur);

Учтите, что при изменении данных он должен иметь одинаковый размер в байтах, иначе вы перезапишете другие данные в вашем файле.

1 голос
/ 23 февраля 2010

Для чтения и записи используется один и тот же указатель положения. Следовательно, если вы хотите иметь возможность читать последовательные значения, для перезаписи значения вы должны перематывать указатель на позицию, которая была прочитана, верно?

Тем не менее, в вашем случае, вероятно, было бы более эффективно считывать блоки данных, а затем преобразовывать их в память и записывать обратно.

0 голосов
/ 23 февраля 2010

Во-первых, вы должны ВСЕГДА проверять фактически открытый файл:

file.open(path, ios::in|ios::out|ios::binary|ios::ate);
if ( ! file.is_open() ) {
    throw "open failed";
}

Тогда вы должны ВСЕГДА проверять, что чтение и запись, которые вы ожидаете работать, сработали:

if ( ! file.read((char*)&buffer,sizeof(char)) ) {
   throw "read failed";
}

И, наконец, вы должны проверить, что комбинация открытых флагов, которые вы используете, действительна для вашей конкретной платформы - см. Почему я не могу читать и добавлять с помощью std :: fstream в Mac OS X? для некоторого обсуждения этого - я бы предложил удалить флаг ios :: ate в вашем коде.

...