WinAPI 文件输入/输出使用 std::strings 而不是 char 数组?

发布于 2024-09-18 13:04:38 字数 787 浏览 14 评论 0原文

由于性能原因,我不想只使用一次 fstream。使用带有 std::string 的 WinAPI 函数而不是普通的 char 数组似乎是一个非常糟糕的主意。总而言之,我希望您告诉我为什么以下代码片段不起作用(空 stBuffer 保持为空)以及我需要做什么才能修复它。

提前致谢!

std::size_t Get(const std::string &stFileName, std::string &stBuffer)
{
    HANDLE    hFile        = ::CreateFileA(stFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    DWORD    dwBytesRead    = 0;

    if(hFile != INVALID_HANDLE_VALUE)
    {
        DWORD    dwFileSize    = ::GetFileSize(hFile, NULL);

        stBuffer.reserve(dwFileSize + 1);
        ::ReadFile(hFile, &stBuffer[0], dwFileSize, &dwBytesRead, NULL);
        stBuffer[dwFileSize] = '\0';
        ::CloseHandle(hFile);
    }

    return dwBytesRead;
}

due to performance reasons I didn't feel like using fstream for just one time. Seems like a very bad idea to use WinAPI functions with a std::string instead of a plain char array. All in all I would like you to tell me why the following snippet just won't work (empty stBuffer stays empty) and what I'd need to do to get it fixed.

Thanks in advance!

std::size_t Get(const std::string &stFileName, std::string &stBuffer)
{
    HANDLE    hFile        = ::CreateFileA(stFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    DWORD    dwBytesRead    = 0;

    if(hFile != INVALID_HANDLE_VALUE)
    {
        DWORD    dwFileSize    = ::GetFileSize(hFile, NULL);

        stBuffer.reserve(dwFileSize + 1);
        ::ReadFile(hFile, &stBuffer[0], dwFileSize, &dwBytesRead, NULL);
        stBuffer[dwFileSize] = '\0';
        ::CloseHandle(hFile);
    }

    return dwBytesRead;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

踏月而来 2024-09-25 13:04:38

由于 std::string 可以包含嵌入的 '\0' 字符,因此它必须以单独的方式跟踪其自身的长度。
您的问题是 std::string::reserve() 不会更改字符串的长度。它只是预先分配一些内存供字符串增长。解决方案是使用 std::string::resize() 并让 WinAPI 函数覆盖字符串内容。

旁注:目前,不能保证 std::string 使用连续的缓冲区,但据我所知,所有当前的实现都使用连续的缓冲区,并且这将是下一个标准。

Because a std::string can contain embedded '\0' characters, it has to keep track of its own length in a separate way.
Your problem is that std::string::reserve() does not change the length of the string. It just pre-allocates some memory for the string to grow into. The solution is to use std::string::resize() and let the WinAPI function overwrite the string contents.

As a side-note: Currently, it is not guaranteed that std::string uses a contiguous buffer, but to my knowledge, all current implementations do use a contiguous buffer and it will be a requirement in the next standard.

梦断已成空 2024-09-25 13:04:38

考虑 reserve()resize() 成员之间的差异。所以解决方案是:

stBuffer.resize(dwFileSize + 1);

Consider difference between reserve() and resize() members. So the solution would be:

stBuffer.resize(dwFileSize + 1);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文