Я пытаюсь импортировать большой объем данных из файла в boost :: dynamic_bitset. Для этого я надеялся использовать istream_iterator, который соответствует размеру блока dynamic_bitset (uint32_t).
Как показано ниже, я устанавливаю свой ifstream, используя местоположение импортируемого файла. Однако, как только я инициализирую istream_iterator с помощью ifstream, устанавливается бит сбоя ifstream.
Любой совет относительно того, почему это происходит?
ifstream memHashes (hashFileLocation, ios::in | ios::binary);
if(memHashes.is_open() == false || memHashes.good() == false) { break; }
std::istream_iterator<uint32_t> memHashesIt(memHashes);
std::istream_iterator<uint32_t> memHashesEOFIt;
По данным cplusplus.com:
failbit обычно устанавливается операцией ввода, когда ошибка была
связаны с внутренней логикой самой операции, поэтому другие
операции на потоке могут быть возможны. Хотя бадбит это вообще
устанавливается, когда ошибка связана с потерей целостности потока, что
может сохраняться, даже если на
поток. Badbit можно проверить независимо, вызвав функцию-член
плохой.
Редактировать:
Хэш содержит 160-битные хэши, созданные реализацией SHA1 в отдельном C-приложении. В этом файле несколько тысяч хэшей. Я хотел бы прочитать 5 блоков по 4 байта вместо 20 блоков по 1 байту (отсюда мое использование uint32_t в качестве размера блока). Я извлек соответствующий код из приложения C, который показывает производимые хеши, а затем записано в файл:
#define HASH_SIZE 20 // 160 bits / 8 bits per byte = 20 bytes
FILE *fp;
fp = fopen(hash_filename, "wb");
if (!fp) {
MSG("Hash dump file cannot be opened");
fclose(fp);
return NULL;
}
uint8_t *p;
unsigned char hash[HASH_SIZE];
SHA1((unsigned char*)p, LENGTH_TO_HASH, hash);
fwrite(hash, HASH_SIZE, 1, fp);
std::istream_iterator<T>
использовать вход operator>>()
для объектов типа T
, То есть он предполагает форматированный ввод. При построении он пытается прочитать первый элемент, который может вызвать std::istream
получить std::ios_base::failbit
задавать.
Я думаю, что инициализация будет читать uint32_t из потока. Тип uint32_t является псевдонимом для unsigned или unsigned long. У меня такое ощущение, что ваш файл не содержит чисел, но вы ожидаете (см., Например, ios_base :: binary openmode) некоторое упакованное нетекстовое представление, которое будет прочитано потоком. Если это так, то ваши ожидания просто неверны, но трудно сказать, не зная больше о вашей программе. Одно замечание: если вы читаете istream_iterator до конца, у вас всегда будут установлены как eofbit, так и failbit. Я предполагаю, что у вас есть только набор битов сбоя, который предлагает ошибку синтаксического анализа.
Проблема в том, что у вас есть двоичные данные.
istream_iterator
а также istreambuf_iterator
использование operator>>
читать данные. Для uint_32_t это означает, что он будет читать текст, читаемый человеком, и преобразовывать его в целое число. Это не удастся (большую часть времени) для двоичных данных.
У вас есть другое представление о скорости.
Чтение 4 байтов за раз вряд ли будет быстрее, чем чтение 1 байта за раз (это сделает код более сложным, что может замедлить его, но не будет никакой разницы в скорости чтения). Это потому, что чтение из потока буферизовано. Огромный кусок уже был считан в буфер, когда вы выполняете чтение, он просто копирует его из одного места в другое.
Что вы действительно хотите сделать, это определить класс, скопировать данные как единое целое в ваш класс:
class ShaMine
{
std::vector<char> data;
public:
ShaMine(): data(20, '\0') {}
friend std::istream& operator>>(std::istream& s, ShaMine& dst)
{
return s.read(&data[0], 20);
}
void poop(std::ostream& s)
{
s << "Hi there: Char 0 is :" << (int) data[0] << "\n";
}
};
int main()
{
std::ifstream sfile("FILE");
for(std::istream_iterator<ShaMine> loop(sfile); loop != std::istream_iterator<ShaMine>(); ++lop)
{
loop->poop(std::cout);
}
};