使用 std::strings 而不是 char 数组的 WinAPI 文件输入/输出?
Posted
技术标签:
【中文标题】使用 std::strings 而不是 char 数组的 WinAPI 文件输入/输出?【英文标题】:WinAPI File In-/Output with std::strings instead of char arrays? 【发布时间】:2010-09-09 09:22:45 【问题描述】:由于性能原因,我不想只使用一次 fstream。使用带有 std::string 而不是普通 char 数组的 WinAPI 函数似乎是一个非常糟糕的主意。总而言之,我想让你告诉我为什么下面的 sn-p 不起作用(空的 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;
【问题讨论】:
我没有看到将 std::strings 与 winAPI 一起使用的问题。我正在我的项目中这样做。 虽然对于 VC(我认为是所有主要的编译器)标准库std::string
有一个连续的缓冲区,但 C++03 不能保证这一点。 C++0x 将保证在此之前std::vector<char>
将是 "clean" 解决方案。
【参考方案1】:
因为std::string
可以包含嵌入的'\0'
字符,所以它必须以单独的方式跟踪自己的长度。
您的问题是 std::string::reserve()
不会更改字符串的长度。它只是为要增长的字符串预先分配一些内存。解决方法是使用std::string::resize()
,让WinAPI函数覆盖字符串内容。
附带说明:目前,不能保证std::string
使用连续缓冲区,但据我所知,所有当前实现都使用连续缓冲区,这将是下一个标准的要求。
【讨论】:
非常感谢的解释!【参考方案2】:考虑reserve()
和resize()
成员之间的区别。所以解决方案是:
stBuffer.resize(dwFileSize + 1);
【讨论】:
嗯,那应该是.resize(dwFileSize)
——+1
是肤浅的。
@Dummy00001 - 编写代码以显式空终止文件内容。除非这是错误的,否则需要 +1。
@Steve:哎呀。你是对。 '\0'
终止在原始代码中也是错误的:std::string
不需要。
恕我直言,这不是由你来决定的。如其他地方所述,std::string 可以包含嵌入的空字符。以上是关于使用 std::strings 而不是 char 数组的 WinAPI 文件输入/输出?的主要内容,如果未能解决你的问题,请参考以下文章
比较两个 std::strings 以查看它们是不是匹配 c++ [关闭]
用字符串文字初始化时,std::strings 是不是以 '\0' 结尾?