Я хочу написать массив в файл, сжимая его, когда я иду.Чтение и запись массива в сжатый файл с boost iostreams
Позже я хочу прочитать массив из этого файла, распаковывая его, когда я иду.
Boost's 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