std :: ios :: failue (ios :: badbit) проблема с fstream.write () - PullRequest
2 голосов
/ 13 ноября 2010

Последние несколько часов я пытался отлаживать свой код и не мог понять проблему.В конце концов я настроил свой файловый поток на выдачу исключений на failbit, и я обнаружил, что мой файловый поток по какой-то причине устанавливает битовый бит.У меня нет абсолютно никакой причины, по которой устанавливается отказоустойчивый бит, потому что все, что я делаю, - это записываю 2048-байтовые куски данных в поток, пока внезапно не произойдет сбой (в одном и том же месте каждый раз).хотел бы показать вам мой код, чтобы увидеть, может ли кто-нибудь увидеть проблему и, возможно, увидеть, что может вызвать сбой std :: ios :::

bool abstractBlock::encryptBlockRC4(char* key)
{//Thic encryption method can be chunked :)
 getStream().seekg(0,std::ios::end);
 int sLen = int(getStream().tellg())-this->headerSize;
 seekg(0);//Seek to beginning of Data
 seekp(0);
 char* encryptionChunkBuffer = new char[2048]; //2KB chunk buffer
 for (int chunkIterator =0; chunkIterator<sLen; chunkIterator+=2048)
 {
  if (chunkIterator+2048<=sLen)
  {
   getStream().read(encryptionChunkBuffer,2048);
   char* encryptedData = EnDeCrypt(encryptionChunkBuffer,2048,key);
   getStream().write(encryptedData,2048);
   free(encryptedData);
  }else{
   int restLen = sLen-chunkIterator;
   getStream().read(encryptionChunkBuffer,restLen);
   char* encryptedData = EnDeCrypt(encryptionChunkBuffer,restLen,key);
   getStream().write(encryptedData,restLen);
   delete  encryptedData;
  }
 }
 delete [] encryptionChunkBuffer;
 dataFlags |= DATA_ENCRYPTED_RC4; // Set the "encryted (rc4)" bit
 seekp(0); //Seek tp beginning of Data
 seekg(0); //Seek tp beginning of Data
 return true;
}

Приведенный выше код по существу шифрует файл, используя2048 кусков.Он в основном читает 2048 байт, шифрует его и затем записывает обратно в поток (перезаписывает «незашифрованные» данные, которые были там ранее).getStream() просто возвращает дескриптор fstream в файл, с которым работает.

Ошибка всегда возникает, когда chunkIterator == 86116352 в строке getStream().write(encryptedData,2048);

Я знаю, что мой код может бытьтрудно декодировать, но, может быть, вы можете сказать мне некоторые возможные вещи, которые могут вызвать сбой бит?В настоящее время я думаю, что проблема заключается в том, что я читаю / записываю в поток, и это может вызывать проблемы, но, как я уже упоминал, любые идеи, которые могут вызвать сбой, могут помочь мне больше исследовать проблему.

1 Ответ

1 голос
/ 13 ноября 2010

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

C ++ 03, §27.5.1p1, Требования к буферу потока

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

Как правило, эти состоянияуправляются определенным потоковым буфером.

C ++ 03, §27.8.1.1p2, Шаблон класса basic_filebuf

Ограничения на чтение и запись последовательности, контролируемой объектомкласс basic_filebufте же, что и для чтения и записи с использованием стандартных файлов FI.

fstream, ifstream и ofstream используют filebufs.

C99, §7.19.5.3p6, функция fopen

Когда файл открывается в режиме обновления («+» в качестве второго или третьего символа в приведенном выше списке значений аргументов режима), ввод и вывод могут выполняться в связанном потоке.Однако за выводом не должен следовать прямой ввод без промежуточного вызова функции fflush или функции позиционирования файла (fseek, fsetpos или rewind), а за вводом не должен непосредственно следовать вывод без промежуточного вызова позиционирования файлафункция, если операция ввода не встречает конец файла.

Вам может потребоваться поискать эти вызовы для перевода в терминологию iostreams, но это довольно просто.


Вы иногда освобождаете результат EnDeCrypt, а иногда удаляете его (но с удалением из одного объекта, а не с формой массива);это, скорее всего, не способствует возникновению проблемы, которую вы видите, но это либо ошибка с вашей стороны, либо, что менее вероятно, со стороны разработчика EnDeCrypt.


Вы используете:

char* encryptionChunkBuffer = new char[2048]; //2KB chunk buffer
//...
getStream().read(encryptionChunkBuffer,2048);
//...
delete[] encryptionChunkBuffer;

Но было бы лучше и проще в использовании:

vector<char> encryptionChunkBuffer (2048); //2KB chunk buffer
//...
getStream().read(&encryptionChunkBuffer[0], encryptionChunkBuffer.size());
//...
// no delete

Если вы не хотите вводить encryptionChunkBuffer.size () дважды, используйте для этого локальную константу.

...