我正在尝试使用解压缩 .7z(或 .xz 或 .lzma)文件
使用以下代码:
vector<T> readFromCompressedFile(string input_file_path, string output_file_path)
{
namespace io = boost::iostreams;
stringstream strstream;
ifstream file(input_file_path.c_str(), ios_base::in | ios_base::binary);
ofstream out(output_file_path, ios_base::out | ios_base::binary);
boost::iostreams::filtering_istream in;
in.push(io::lzma_decompressor());
in.push(file);
io::copy(in, out);
cout<<strstream.str()<<endl;
Run Code Online (Sandbox Code Playgroud)
代码可以编译,但我收到复制方法引发的运行时异常(lzma_error)
warning: GDB: Failed to set controlling terminal: Operation not permitted
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::iostreams::lzma_error> >'
what(): lzma error: iostream error
Run Code Online (Sandbox Code Playgroud)
我尝试使用filtering_streambuf过滤器,但没有成功,该过滤器的代码块与gzip示例的代码非常相似
https://www.boost.org/doc/libs/1_67_0/libs/iostreams/doc/classes/gzip.html#examples
不过,我可以使用 gzip 和上述代码来解压缩使用 gzip 压缩的文件。看来这个问题仅限于LZMA算法。
有人有同样的问题吗?有任何想法吗?
谢谢
您的代码很好,这不是一个错误。
起初,我遇到了与上述相同的问题,但经过一番研究,我发现这是因为boost iostreams库调用了XZ库提供的lzma_stream_decoder来做解码工作,而.lzma或.7z格式文件不支持lzma_stream_decoder 。 如果尝试使用 boost iostreams 库解码.lzma或.7z格式文件,则会抛出错误代码为LZMA_FORMAT_ERROR的异常。请参考XZ源代码xz-5.2.4.tar.gz中的错误码定义
\src\liblzma\api\lzma\base.h
LZMA_FORMAT_ERROR = 7,
/**<
* \brief File format not recognized
*
* The decoder did not recognize the input as supported file
* format. This error can occur, for example, when trying to
* decode .lzma format file with lzma_stream_decoder,
* because lzma_stream_decoder accepts only the .xz format.
*/
Run Code Online (Sandbox Code Playgroud)
请参考boost iostreams库的源代码:lzma.cpp
您可以尝试解码.xz文件,不会有问题。我已经使用您在 Windows X64 和 boost 库 1.66.0 上提供的相同代码对此进行了测试。
顺便说一句,@ sehe提供的用于错误检测的代码具有误导性:
try {
io::copy(in, out);
} catch(io::lzma_error const& e) {
std::cout << boost::diagnostic_information(e, true);
std::cout << e.code() << ": " << e.code().message() << "\n";
}
Run Code Online (Sandbox Code Playgroud)
应该:
try {
io::copy(in, out);
} catch(io::lzma_error const& e) {
std::cout << boost::diagnostic_information(e, true);
std::cout << e.error() << ": " << e.code().message() << "\n";
}
Run Code Online (Sandbox Code Playgroud)
然后你会发现抛出异常的错误代码是:7(LZMA_FORMAT_ERROR)。
我可以确认同样的问题。
使用其他工具解压lzma文件没有问题。可能存在版本控制问题,或者可能存在错误。这是代码的清理版本,没有太多噪音,消除了一些可疑的样式 ( using namespace std) 并尝试获取更多错误信息:
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/lzma.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <fstream>
#include <iostream>
namespace io = boost::iostreams;
void foo(std::string input_file_path, std::string output_file_path) {
namespace io = boost::iostreams;
std::ifstream file(input_file_path, std::ios::binary);
std::ofstream out(output_file_path, std::ios::binary);
boost::iostreams::filtering_istreambuf in;
in.push(io::lzma_decompressor());
in.push(file);
try {
io::copy(in, out);
} catch(io::lzma_error const& e) {
std::cout << boost::diagnostic_information(e, true);
std::cout << e.code() << ": " << e.code().message() << "\n";
} catch(boost::exception const& e) {
std::cout << boost::diagnostic_information(e, true);
}
}
int main() {
foo("test.cpp.lzma", "output.txt");
}
Run Code Online (Sandbox Code Playgroud)
在我的系统上,我已经验证测试程序和 /usr/bin/lzma 都链接到完全相同版本的库,因此此时版本控制问题似乎不太可能:
我认为应该向上游报告该问题(在boost Trac、邮件列表或github 问题上)