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);
st开发者_如何学CBuffer.reserve(dwFileSize + 1);
::ReadFile(hFile, &stBuffer[0], dwFileSize, &dwBytesRead, NULL);
stBuffer[dwFileSize] = '\0';
::CloseHandle(hFile);
}
return dwBytesRead;
}
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.
Consider difference between reserve()
and resize()
members. So the solution would be:
stBuffer.resize(dwFileSize + 1);
精彩评论