Необходимо считать в std::string байты файла. Одно из требований: поддержка юникодных имен файлов. Реализовал следующую функцию:
std::string ReadFileBinary(const std::filesystem::path& filename)
{
std::wifstream file(filename, std::ios::binary);
if (!file.is_open())
{
// выброс проектного исключения
}
std::stringstream ss;
ss << file.rdbuf();
std::string binary_data((const char*)ss.str().c_str(), ss.str().size());
return binary_data;
}
Далее реализовл тестирование следующим образом (google test):
TEST(string_utils, TestReadFileBinary)
{
char c_file_data[] = { 0x60, 0xED, 0xDA, 0xCD, 0xAB, 0xDD, 0xDD, 0xDD, 0xCE, 0xDA, 0xBC, 0xD1, 0x24 };
std::string file_data(c_file_data, sizeof(c_file_data));
std::string readed_file_data =
ReadFileBinary("test_read_file_binary.bin");
EXPECT_EQ(file_data, readed_file_data);
}
Содержимое файла test_read_file_binary.bin:
Тест проваливается со следующей ошибкой:
error: Expected: file_data
Which is: "`\xED\xDA\xCD\xAB\xDD\xDD\xDD\xCE\xDA\xBC\xD1$"
To be equal to: readed_file_data
Which is: "010FF3B8"
При работе с ifstream а не wifstream считывание производится корректно, но не обрабатываются юникодные имена файлов.
После анализа пришел к выводу, что средствами STL данный функционал реализовать невозможно ввиду отсутствия адекватной поддержки Unicode со стороны С++. Реализовал с помощью WinAPI. Код:
void WriteFileBinary(const std::filesystem::path& filename, const std::string &data)
{
DWORD creation_disposition = exists(filename) ? TRUNCATE_EXISTING : CREATE_NEW;
DWORD bytes_to_write = data.size();
DWORD bytes_written = 0;
HANDLE h_file = CreateFileW
(
filename.generic_wstring().c_str(),
GENERIC_WRITE,
0,
nullptr,
creation_disposition,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (h_file == INVALID_HANDLE_VALUE)
{
// throw
}
bool write_status = WriteFile
(
h_file,
data.c_str(),
bytes_to_write,
&bytes_written,
nullptr
);
if (!write_status)
{
CloseHandle(h_file);
// throw
}
if (bytes_written != bytes_to_write)
{
CloseHandle(h_file);
// throw
}
CloseHandle(h_file);
}
std::string ReadFileBinary(const std::filesystem::path& filename)
{
HANDLE h_file = CreateFileW
(
filename.generic_wstring().c_str(),
GENERIC_READ,
0,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (h_file == INVALID_HANDLE_VALUE)
{
// throw
}
DWORD file_len = file_size(filename);
DWORD bytes_read = 0;
char *file_data = (char*)malloc(file_len);
if (file_data == nullptr)
{
CloseHandle(h_file);
// throw
}
bool read_status = ReadFile
(
h_file,
file_data,
file_size(filename),
&bytes_read,
nullptr
);
if (!read_status)
{
free(file_data);
CloseHandle(h_file);
// throw
}
if (bytes_read != file_len)
{
free(file_data);
CloseHandle(h_file);
// throw
}
std::string result(file_data, file_len);
CloseHandle(h_file);
free(file_data);
return result;
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы он был сосредоточен только на одной проблеме
Есть некоторая таблица в которую из базы данных через промежуточную структуру подгружаются данные(вектор объектов класса)В структуре данные...