我正在尝试使用
解压缩.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;
代码编译,但我得到了复制方法引发的运行时异常(lzma_error)
警告:GDB:设置控制终端失败:不允许操作 在抛出&#39; boost :: exception_detail :: clone_impl&gt;&#39;的实例后终止调用 what():lzma错误:iostream错误
我试过没有运气使用filtering_streambuf过滤器,其中一段代码与gzip示例的代码非常相似
https://www.boost.org/doc/libs/1_67_0/libs/iostreams/doc/classes/gzip.html#examples
但是我能够解压缩用gzip压缩的文件和上面的代码。 似乎问题仅限于LZMA算法。
有同样问题的人吗?有什么想法吗?
谢谢
答案 0 :(得分:2)
我可以确认同样的问题。
使用其他工具解压缩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");
}
在我的系统上,我已经验证测试程序和/ usr / bin / lzma都链接到完全相同的库版本,因此此时版本问题似乎不太可能:
我认为应该在上游(boost Trac,邮件列表或github issue)报告问题
答案 1 :(得分:2)
您的代码很好,这不是错误。
起初,我遇到了与上述相同的问题,但是经过一番研究,我发现这是因为boost iostreams库调用了 XZ 库提供的 lzma_stream_decoder 做解码工作, lzma_stream_decoder 不支持 .lzma 或 .7z 格式文件。如果您尝试使用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.
*/
请参考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";
}
应为:
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";
}
然后您将发现抛出以下错误代码的错误代码是:7(LZMA_FORMAT_ERROR)。