Входящий / исходящий файл WinAPI с std :: strings вместо массивов символов? - PullRequest
0 голосов
/ 09 сентября 2010

из-за проблем с производительностью я не хотел использовать fstream всего один раз.Похоже, очень плохая идея использовать функции WinAPI с std :: string вместо обычного массива 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;
}

Ответы [ 2 ]

1 голос
/ 09 сентября 2010

Поскольку std::string может содержать встроенные символы '\0', он должен отдельно отслеживать свою длину.Ваша проблема в том, что std::string::reserve() не меняет длину строки.Он просто предварительно выделяет память для роста строки.Решение состоит в том, чтобы использовать std::string::resize() и позволить функции WinAPI перезаписать содержимое строки.

В качестве примечания: в настоящее время не гарантируется, что std::string использует непрерывный буфер, но, насколько мне известновсе текущие реализации используют непрерывный буфер, и это будет требованием в следующем стандарте.

1 голос
/ 09 сентября 2010

Рассмотрим разницу между reserve() и resize() членами. Таким образом, решение будет:

stBuffer.resize(dwFileSize + 1);
...