配列をファイルに書き出し、圧縮します。boostのiostreamで圧縮ファイルを読み書きする
後で、私はそのファイルから配列を読み込み、解凍します。
ブーストのIostreamsは良い方法のように思えるので、次のコードを作成しました。残念なことに、出力と入力データは最終的には比較されません。しかし、これは非常に近いです:
Output Input
0.8401877284 0.8401880264
0.3943829238 0.3943830132
0.7830992341 0.7830989957
0.7984400392 0.7984399796
0.9116473794 0.9116470218
0.1975513697 0.1975509971
0.3352227509 0.3352229893
これは、各フロートの最下位バイトが変更されていることを示唆しています。しかし圧縮は無損失でなければならないので、これは予期しないか、望ましくない。何がありますか?
//Compile with: g++ test.cpp --std=c++11 -lz -lboost_iostreams
#include <fstream>
#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/zlib.hpp>
#include <cstdlib>
#include <vector>
#include <iomanip>
int main()
{
using namespace std;
using namespace boost::iostreams;
const int NUM = 10000;
std::vector<float> data_out;
std::vector<float> data_in;
data_in.resize(NUM);
for(float i=0;i<NUM;i++)
data_out.push_back(rand()/(float)RAND_MAX);
{
ofstream file("/z/hello.z", ios_base::out | ios_base::binary);
filtering_ostream out;
out.push(zlib_compressor());
out.push(file);
for(const auto d: data_out)
out<<d;
}
{
ifstream file_in("hello.z", ios_base::in | ios_base::binary);
filtering_istream in;
in.push(zlib_decompressor());
in.push(file_in);
for(float i=0;i<NUM;i++)
in>>data_in[i];
}
bool all_good=true;
for(int i=0;i<NUM;i++){
cout<<std::setprecision(10)<<data_out[i]<<" "<<data_in[i]<<endl;
all_good &= (data_out[i]==data_in[i]);
}
cout<<"Good? "<<(int)all_good<<endl;
}
そして、はい、私は非常に多く、むしろ一度に全体のベクトルブロックを押したり引っ張っよりも、私のやり方では、ストリーム演算子を使用することを好みます。
サンプルから圧縮を外しても問題が発生しますか? –
はい、それは、ちょうどそれを試みました。浮動小数点数を文字列としてファイルに出力しています。セパレータもありません。 1より小さい値を保存することができれば、遠隔的に賢明なものを手に入れることができます。 –
私は区切り文字が圧縮/解凍に必要ではないはずがないと思います。浮動小数点数が内部のバイトバッファにプッシュされ、圧縮に十分なデータが利用できるようになると想像します。圧縮解除も同様に機能します。データは十分な情報が利用可能になると、内部バッファに読み込まれ、そこから引き出されます。 – Richard