下面这个从zip中解压一个文件出来的函数,有时会在outFile.write()的内部触发MSVC的invalid parameter handler,默认是崩掉。
而触发invalid parameter handler的原因是outFile内部的文件句柄fh是-1。
此时查看outFile的成员_Mystate是0(0是goodbit。这个_Mystate是个bit掩码,出错误会置位其中的badbit或者failbit)。
std::ofstream的operator!()实际执行的是fail(),它的实现如下:
_NODISCARD bool __CLR_OR_THIS_CALL fail() const noexcept /* strengthened */ {
return rdstate() & (ios_base::badbit | ios_base::failbit);
}
_NODISCARD iostate __CLR_OR_THIS_CALL rdstate() const noexcept /* strengthened */ {
return _Mystate;
}
诡异的原因是,什么情况下,能通过打开文件时的fail()检查,但实际并未打开文件,句柄为-1?
或者句柄什么时候变成了-1?
outFile(destPath, std::ios::binary)的标志需要换成(std::ios::binary | std::ios::out | std::ios::trunc) ?
bool ExtractSingleFileFromZip(zip *archive, const zip_stat_t &fileStat,
const std::filesystem::path &destPath) {
zip_file *zf = zip_fopen_index(archive, fileStat.index, 0);
if (!zf) {
return false;
}
SCOPE_EXIT { zip_fclose(zf); };
std::ofstream outFile(destPath, std::ios::binary);
if (!outFile) {
return false;
}
if (fileStat.size == 0)
return true;
std::vector<uint8_t> buffer;
try {
buffer.resize(fileStat.size);
} catch ([[maybe_unused]] const std::bad_alloc &e) {
return false;
}
if (zip_fread(zf, buffer.data(), buffer.size()) != fileStat.size) {
return false;
}
outFile.write((const char *)buffer.data(), buffer.size());
return !outFile.fail() && !outFile.bad();
}
--
FROM 221.218.167.*