나는 그 iostreams 패키지를 부스트하고 문서를 조금 더 얇게 찾는 것이 처음이다. 잘만되면 누군가 나를 똑바로 세울 것입니다. 압축 된 스트림을 읽는 동안 잠시 쓴 C# 스트림 코드의 작은 조각을 변환하려고합니다.boost :: iostreams resources를 관리하는 것
byte[] data = new byte[length - 1];
file.Read(data, 0, data.Length);
Stream ret = new ZlibStream(new MemoryStream(data), CompressionMode.Decompress, true);
return ret;
파일의 일부 데이터는 zlib 압축 해제기를 제공하는 메모리 버퍼로 읽어들입니다. 스트림 소비자는 시간이 지남에 따라 선택을 취소하고 완료되면 가비지 수집기와 결합 된 Close()
을 호출하면 모든 리소스가 정리됩니다. 참고 : 중요한 차이점은 전체 파일의 압축을 풀려고하지 않고 단지 하나의 작은 부분 만 압축하려고한다는 것입니다. 파일은 이미 내부 위치로 검색되고 길이는 파일의 전체 크기에 비하여 작습니다.
나는 Boost를 사용하여 C++ 코드에서 이와 동등한 최상의 결과를 얻으려고합니다. 지금까지 나는이 도덕적 위 (안된)에 해당이 : 나는 스트림을 삭제에 대한 걱정에서 소비자를 저장할 것 shared_ptr
에 싸여 filtering_stream를 반환 할 수 가정
char * data = new char[length - 1];
_file.read(data, length - 1);
io::stream_buffer<io::basic_array_source<char> > buffer(data, length - 1);
io::filtering_stream<io::input> * in = new io::filtering_stream<io::input>;
in->push(io::zlib_decompressor());
in->push(buffer);
return in;
, 그러나 나는 또한이 그 데이터 버퍼가 그곳에 새롭게 추가되었습니다. 이상적으로는 고객이 스트림에서 close()
으로 전화를 걸고 일부 메커니즘 (예 : 콜백)이 필터의 기본 리소스를 정리하는 것이 좋습니다. 소비자가 스트림을 명시 적 릴리스 함수에 전달하도록 요구하는 것은 가능하지만, 기본 데이터 버퍼를 처음부터 다시 얻는 방법에 대해서는 여전히 확실하지 않습니다.
클리너 대체 솔루션도 환영합니다.
나는 표준 : : 벡터 백업 드라이버에 대한 고양이 플러스 플러스로 주석에 압류 느슨하게 해봤 1
업데이트. 그건 내가 한 일이 아니지만, 지금까지 내가 생각해 낸 것입니다. 다음 코드에서, boost :: shared_array 지원 드라이버는 boost 드라이버 예제를 기반으로합니다.
namespace io = boost::iostreams;
class shared_array_source
{
public:
typedef char char_type;
typedef io::source_tag category;
shared_array_source (boost::shared_array<char> s, std::streamsize n)
: _data(s), _pos(0), _len(n)
{ }
std::streamsize read (char * s, std::streamsize n)
{
std::streamsize amt = _len - _pos;
std::streamsize result = (std::min)(amt, n);
if (result != 0) {
std::copy(_data.get() + _pos, _data.get() + _pos + result, s);
return result;
}
else {
return -1;
}
}
private:
boost::shared_array<char> _data;
std::streamsize _pos;
std::streamsize _len;
};
은 그 때 나는 스트림을 돌려 내 기능이
io::filtering_istream * GetInputStream (...)
{
// ... manipulations on _file, etc.
boost::shared_array<char> data(new char[length - 1]);
_file.read(data.get(), length - 1);
shared_array_source src(data, length - 1);
io::stream<shared_array_source> buffer(src);
io::filtering_istream * in = new io::filtering_istream;
in->push(io::zlib_decompressor());
in->push(buffer);
// Exhibit A
// uint32_t ui;
// rstr->read((char *)&ui, 4);
return in;
}
그리고 테스트 프로그램 내 주요 기능에
:int main() {
boost::iostreams::filtering_istream * istr = GetInputStream();
// Exhibit B
uint32_t ui;
rstr->read((char *)&ui, 4);
return 0;
}
내가 포인터를 반환하고있어 사실을 무시 그것은 결코 풀릴 수 없을 것입니다 - 저는 이것을 가능한 한 간단하게 유지하고 있습니다. 이걸 실행할 때 어떻게됩니까? Exhibit A에서 코드의 주석을 제거하면 ui
에 올바른 판독 값이 표시됩니다. 그러나 Exhibit B를 클릭하면 Boost (때로는)에서 깊이 깊고 깊숙이 박살납니다. 잘 쓰레기, 나는 범위를 벗어났다. 그리고 물건은 부서졌다, 일부 지방의 것은 deconstructing하고, 모든 것을 골라 내야한다. data
은 shared_array에 있으며 in
은 힙에 있으며 압축 프로그램은 docs에 따라 생성됩니다.
부스트 생성자 또는 함수 중 하나가 스택의 객체에 대한 참조 (즉, io :: stream 또는 filtering_stream의 푸시)를 가져 오는 중 하나입니까? 그렇다면, 나는 힙에있는 관리되지 않는 오브젝트를 가지고 사각형으로 돌아 간다.
항상 0입니까? 아무 가치도 부여하지 않습니다. –