首页 > 解决方案 > 当 ifstream 读取到大于 ~1MiB 的缓冲区时,为什么程序会崩溃?

问题描述

我正在使用以下代码:

const size_t MonaBuffSize = 1024 * 1000;
std::ifstream file(Path.string(), std::ifstream::binary);
MD5_CTX md5Context;
MD5_Init(&md5Context);
char buf[MonaBuffSize];
while (file.good()) {
    file.read(buf, sizeof(buf));
    MD5_Update(&md5Context, buf, file.gcount());
}
unsigned char result[MD5_DIGEST_LENGTH];
MD5_Final(result, &md5Context);

当我将 MonaBuffSize 设置为 1024 * 1024 - 调用 file.read 函数时程序崩溃。

ifstream.read() 函数中是否有任何缓冲区大小限制?我知道使用较小的缓冲区可能会更好,但我想了解这里有什么问题。

我正在使用 Visual Studio 2019,C++ 17。

编辑:按照评论中的建议,我回到了与 boost::iostreams::mapped_file_source 一起使用的上一个方法:

const std::string md5_from_file(const std::filesystem::path Path, std::uintmax_t Size)
{
        unsigned char result[MD5_DIGEST_LENGTH];
        if (Size > 0) {
            try {
                boost::iostreams::mapped_file_source src;
                src.open(Path.string());
                MD5((unsigned char*)src.data(), src.size(), result);
            }
            catch (std::ios_base::failure const& e)
            {
                MD5((unsigned char*)"", 0, result);
                //MessageBox(NULL, e.what(), "EXCEPTION", MB_YESNO | MB_ICONINFORMATION);
            }
        }
        else {
            MD5((unsigned char*)"", 0, result);
        }
        std::ostringstream sout;
        sout << std::hex << std::setfill('0');
        for (auto c : result) sout << std::setw(2) << (int)c;

        return sout.str();
}

此外,我意识到是 Windows Defender 大大降低了磁盘读取速度,所以我试图加快它的速度是毫无意义的。

标签: c++c++17ifstream

解决方案


推荐阅读