2016-07-19 11 views
0

私はビットセットを使用するプロジェクトで作業しています。提供されるテキストファイルが非常に大きい(> 800M)ので、std :: bitsetに直接ロードするには25秒以上かかるでしょう。だから、テキストファイルをメモリにバイナリファイルをダンプして前処理したい。 8ビットのcharは1ビットに変換されるため、ファイルの読み込みにかかる時間が大幅に短縮されます。正常に動作思わstd :: bitsetをバイナリファイルに書き込んでstd:bitsetにファイルをロードしてください

#include <iostream>  
#include <bitset>   
#include <string> 
#include <stdexcept>  
#include <fstream> 
#include <math.h> 

int main() { 
    const int MAX_SIZE = 19; 
    try { 

     std::string line = "1001111010011101011"; 
     int copy_bypes = (int)ceil((float)MAX_SIZE/8.0); 


     std::bitset<MAX_SIZE>* foo = new (std::nothrow)std::bitset<MAX_SIZE>(line);  // foo: 0000 
     std::ofstream os ("data.dat", std::ios::binary); 
     os.write((const char*)&foo, copy_bypes); 
     os.close(); 


     std::bitset<MAX_SIZE>* foo2 = new (std::nothrow)std::bitset<MAX_SIZE>(); 
     std::ifstream input("data.dat",std::ios::binary); 
     input.read((char*)&foo2, copy_bypes); 
     input.close(); 

     for (int i = foo2->size() -1 ; i >=0 ; --i) { 
      std::cout << (*foo2)[i]; 
     } 
     std::cout <<std::endl; 
    } 
    catch (const std::invalid_argument& ia) { 
     std::cerr << "Invalid argument: " << ia.what() << '\n'; 
    } 
    return 0; 
} 

が、私はこの使用法は本当に生産的環境で正常に動作することができます心配しています:私は、デモ・コードを記述します。

ありがとうございました。

+0

http://stackoverflow.com/questions/5251403/binary-serialization-of-stdbitset – Holt

+1

'std :: bitset * foo = new(std :: nothrow)std ::を参照してください。 bitset (line); ' - なぜあなたはここで動的に割り当てていますか?そして、ポインタのアドレス( '&foo')を' os.write'に与えると、これがどのように「うまくいくか」はわかりません。 – PaulMcKenzie

+0

*提供されているテキストファイルが非常に大きい(> 800M)ので、std :: bitsetに直接ロードするには25秒以上かかる* - 非常に貧弱なディスクシステムです。 – PaulMcKenzie

答えて

0

バイナリの非trivalクラスをファイルに書き込むことは本当に危険です。ビットセットを明確なバイナリデータに変換する必要があります。データが符号なしlong longに収まることがわかっている場合は、bitset <> :: to_ullong()を使用して、そのunsigned long longを書き込み/読み取りできます。あなたがこれをクロスプラットフォームbeetwetにすることを望むならば。 64および32ビットプラットフォームでは、固定サイズのタイプを使用する必要があります。

0

この2行は、あなたがfoo2へのポインタのアドレスを渡している

os.write((const char*)&foo, copy_bypes); 
input.read((char*)&foo2, copy_bypes); 

間違っている、いないstd::bitsetオブジェクトそのもの。しかし、修正されても:

os.write((const char*)foo, copy_bypes); 
input.read((char*)foo2, copy_bypes); 

生産環境で使用することは危険です。ここではstd::bitsetPODtypeであると仮定しており、そのようにアクセスします。しかし、コードが複雑になると、あまりにも多くの文章や読み込みの危険性があり、未定義の動作が起こらないようにするための保護手段はありません。 std::bitsetは便利で高速ではなく、ビットにアクセスするために提供する方法によって表現されます。たとえば、std::vectorまたはstd::stringが提供するように、そのストレージのアドレスを取得する適切な方法はありません。パフォーマンスが必要な場合は、独自の実装を行う必要があります。

+1

コードは間違っています。ポインタ 'foo'と' foo2'のアドレスが渡されていますが、間違っています。 – PaulMcKenzie

+0

@PaulMcKenzieありがとう! – buld0zzr

+0

ありがとう非常に – zhouhongwei

関連する問題