2

ファイルからboost::dynamic_bitsetに大量のデータをインポートしようとしています。これを実現するために、dynamic_bitset(uint32_t)のブロックサイズに一致するistream_iteratorを使用したいと考えていました。

以下に示すように、インポートするファイルの場所を使用して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によると

フェイルビットは通常、エラーが操作自体の内部ロジックに関連している場合に入力操作によって設定されるため、ストリーム上の他の操作が可能になる場合があります。通常、badbitは、エラーにストリームの整合性の喪失が含まれる場合に設定されます。これは、ストリームで別の操作が実行された場合でも持続する可能性があります。badbitは、メンバー関数badを呼び出すことで個別にチェックできます。

編集:

ハッシュには、別のCアプリケーションのSHA1実装によって生成された160ビットのハッシュが含まれています。このファイルには数千のハッシュがあります。1バイトの20ブロックではなく、4バイトの5ブロックを読み取りたい(したがって、ブロックサイズとして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>>()Tstd::istreamstd::ios_base::failbit

于 2013-01-26T22:36:29.793 に答える
0

初期化はストリームからuint32_tを読み取ると思います。タイプuint32_tは、unsignedまたはunsignedlongのエイリアスです。あなたのファイルには数字が含まれていないが、ストリームによって読み取られるパックされた非テキスト表現があることを期待している(たとえば、ios_base :: binary openmodeを参照)という不気味な感じがします。これが事実である場合、あなたの期待は単に間違っていますが、あなたのプログラムについてもっと知らずに言うのは難しいです。ただし、注意点:istream_iteratorを最後まで読んでいる場合は、常にeofbitとfailbitの両方が設定されています。フェイルビットが設定されているだけだと思います。これは、解析エラーを示唆しています。

于 2013-01-26T22:33:13.133 に答える
0

問題は、バイナリ データがあることです。

istream_iteratoristreambuf_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 に答える