不要使用 StorageFile API 将数据保存到本地文件夹。仅在需要时使用它:对于需要您将它们传递到存储文件中的 API 或访问没有真实路径的图片库之类的地方。与传统 API 相比,StorageFile API 非常慢。最糟糕的是,所有文件操作都是异步的,这意味着使用它们很痛苦,调试起来更痛苦。
对于您的场景,如果您熟悉它,我只会使用 std::wofstream:
#include <fstream>
class winRTLog
{
public:
winRTLog(Platform::String^ fileName);
void save(Platform::String^ log);
private:
std::wofstream m_OutStream;
};
winRTLog::winRTLog(Platform::String^ fileName) :
m_OutStream(std::wstring(Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data()) + L"\\" + fileName->Data(), std::ios::app)
{
if (!m_OutStream.is_open())
throw std::runtime_error("Failed to open the log file.");
}
void winRTLog::save(Platform::String^ log)
{
m_OutStream << log->Data();
if (m_OutStream.fail())
throw std::runtime_error("Failed to write to the log file.");
}
或者,您可以使用 Win32 文件 API:
#include <memory>
#include <string>
#include <windows.h>
class winRTLog
{
public:
winRTLog(Platform::String^ fileName);
~winRTLog();
void save(Platform::String^ log);
private:
HANDLE m_LogHandle;
};
winRTLog::winRTLog(Platform::String^ fileName)
{
auto filePath = std::wstring(Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data()) + L"\\" + fileName->Data();
m_LogHandle = CreateFile2(filePath.c_str(), GENERIC_WRITE, 0, OPEN_ALWAYS, nullptr);
if (m_LogHandle == INVALID_HANDLE_VALUE)
throw std::runtime_error("Failed to open the log file: error code " + std::to_string(GetLastError()));
if (SetFilePointer(m_LogHandle, 0, nullptr, FILE_END) == INVALID_SET_FILE_POINTER)
throw std::runtime_error("Failed to set file pointer to the end of file: error code " + std::to_string(GetLastError()));
}
winRTLog::~winRTLog()
{
if (m_LogHandle != INVALID_HANDLE_VALUE)
CloseHandle(m_LogHandle);
}
void winRTLog::save(Platform::String^ log)
{
// Convert to UTF8
std::string utf8;
utf8.resize(4 * log->Length());
auto utf8Length = WideCharToMultiByte(CP_UTF8, 0, log->Data(), static_cast<int>(log->Length()), &utf8[0], static_cast<int>(4 * log->Length()), nullptr, nullptr);
if (utf8Length == 0)
throw std::runtime_error("Failed to convert log message to UTF8: error code " + std::to_string(GetLastError()));
utf8.resize(utf8Length);
// Write to actual log
DWORD bytesWritten;
auto writeResult = WriteFile(m_LogHandle, utf8.data(), static_cast<DWORD>(utf8.length()), &bytesWritten, nullptr);
if (writeResult == FALSE || bytesWritten != utf8.length())
throw std::runtime_error("Failed to write log message to the log file: error code " + std::to_string(GetLastError()));
}
注意,我使用抛出 std::runtime_error 来进行错误处理,例如:您可能希望以不同的方式进行。