2

我正在尝试将大量数据从文件导入到 boost::dynamic_bitset。为此,我希望使用与 dynamic_bitset (uint32_t) 的块大小相匹配的 istream_iterator。

如下所示,我使用要导入的文件的位置来设置我的 ifstream。但是,一旦我使用 ifstream 初始化 istream_iterator,就会设置 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,即使在流上执行不同的操作也可能会持续存在。通过调用成员函数 bad 可以独立检查 badbit。

编辑:

散列包含 160 位散列,由单独的 C 应用程序中的 SHA1 实现生成。该文件中有几千个哈希值。我想读取 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);
4

3 回答 3

2

std::istream_iterator<T>输入operator>>()用于类型的对象T。也就是说,它假定格式化输入。在构造时,它会尝试读取可能导致设置的第一个std::istream元素std::ios_base::failbit

于 2013-01-26T22:36:29.793 回答
0

我认为初始化将从流中读取一个 uint32_t 。类型 uint32_t 是 unsigned 或 unsigned long 的别名。我有一种令人毛骨悚然的感觉,即您的文件不包含数字,但您期望(参见例如 ios_base::binary 开放模式)流可以读取一些打包的非文本表示形式。如果是这种情况,那么您的期望就是错误的,但是如果不了解更多有关您的程序的信息,就很难判断。不过需要注意的是:如果您将 istream_iterator 读到最后,您将始终同时设置 eofbit 和 failbit。我猜你只设置了故障位,这表明存在解析错误。

于 2013-01-26T22:33:13.133 回答
0

问题是你有二进制数据。

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);
     }
};
于 2013-01-27T03:17:04.367 回答