Я пробовал различные идиоматические c C++
решения для чтения файла в std::string
на Windows
, и это доставляло мне кучу головных болей, так как длина std::string
была постоянно неправильной (например, много меньше исходного файла). Все эти же коды прекрасно работали на Linux
.
Следующие функции работают некорректно на Windows
:
#include <boost/filesystem.hpp>
#include <iostream>
#include <sstream>
using namespace boost::filesystem;
using namespace boost::iostreams;
std::string read_string_from_file_using_streams(const path &file_path) {
return read_string_from_file_using_streams(file_path.parent_path(), file_path.filename().string());
}
std::string read_string_from_file_using_streams(const path &parent_directory, const std::string &file_name) {
const auto original_file_path =
parent_directory.string() + (char) path::preferred_separator + file_name;
const std::ifstream input_stream(original_file_path);
if (input_stream.fail()) {
throw std::runtime_error("File is not readable");
}
std::stringstream buffer;
buffer << input_stream.rdbuf(); // Does not read the whole file on Windows!
return buffer.str();
}
std::string read_string_from_file_with_string_pre_allocation(const std::string& path) {
std::ifstream t(path);
std::string str;
t.seekg(0, std::ios::end);
str.reserve(t.tellg()); // Reserves the correct length
t.seekg(0, std::ios::beg);
str.assign(std::istreambuf_iterator<char>(t), // Does not read the whole file on Windows!
std::istreambuf_iterator<char>());
return str;
}
std::string read_string_from_file_using_if_stream(const std::string& path) {
std::ifstream file(path);
return std::string(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()); // Does not read the whole file on Windows!
}
Наконец, следующий стандартный пример кода C
работает правильно:
std::string read_using_c_standard_library(const std::string& path) {
auto f = fopen(path.c_str(), "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
auto string = (char *) malloc(fsize + 1);
fread(string, 1, fsize, f); // This reads the whole file on Windows, finally!
fclose(f);
string[fsize] = 0;
std::string s(string, fsize);
free(string);
return s;
}
Я не понимаю, почему это происходит. Что не так с подходами C++
? Мой пример файла 516 KB
, а функции с ошибками читают только, например 912 bytes
.