#c #mingw #std-filesystem
#c #mingw #std-файловая система
Вопрос:
Чтобы прочитать файл в моем коде, я использую std::filesystem::file_size (https://en.cppreference.com/w/cpp/filesystem/file_size ), чтобы получить его размер. Я использую этот код :
template <typename TYPE>
inline void read_binary_file(const fs::path filename, std::vector<TYPE>amp; result)
{
std::ifstream file(filename, std::ios::in | std::ios::binary);
__ERR_READFILE01__ // file cannot be open
SPDLOG_DEBUG("Reading {}", filename.u8string());
size_t filesize;
try
{
filesize = fs::file_size(filename);
}
catch(fs::filesystem_erroramp; e)
{
std::cout << e.what() << 'n'; abort();
}
assert(filesize%sizeof(TYPE) == 0);
SPDLOG_DEBUG("size of file {}", filesize);
SPDLOG_DEBUG("size of {}", static_cast<std::uintmax_t>(-1));
SPDLOG_DEBUG("size of type {}", sizeof(TYPE));
SPDLOG_DEBUG("size of the reading vector {}", filesize/sizeof(TYPE));
result.resize(filesize/sizeof(TYPE));
file.read(reinterpret_cast<char*>(result.data()), filesize);
file.close();
}
Это работает для большинства файлов, которые мне нужно прочитать, но для файла (~ 3 гигабайта) у меня странная проблема :
[07/12/2020 11:52:42][debug] size of file 18446744072617361848
[07/12/2020 11:52:42][debug] size of 18446744073709551615
[07/12/2020 11:52:42][debug] size of type 4
[07/12/2020 11:52:42][debug] size of the reading vector 4611686018154340462
В документации я могу читать The non-throwing overload returns static_cast<std::uintmax_t>(-1) on errors.
. Но значение 18446744072617361848 отличается от static_cast<std::uintmax_t>(-1)
, поэтому я заблудился….
Мой компилятор — mingw32 :
mingw32-make.exe --version
GNU Make 4.3 Built for Windows32 Copyright (C) 1988-2020 Free Software Foundation, Inc. License GPLv3 : GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
У меня нет проблемы в linux (gcc).
Комментарии:
1. Если вы установите
std::uintmax_t filesize = -1;
(максимальное значение) иSPDLOG_DEBUG("{}", filesize);
что вы получите?
Ответ №1:
Существует ошибка, которая будет исправлена в последних версиях MinGW. cf:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95749
Но событие, которое должно заменить
size_t filesize;
Автор:
std::uintmax_t filesize;
в соответствии с сигнатурой функции :
std::uintmax_t file_size( const std::filesystem::pathamp; p );
Комментарии:
1. Это ничего не меняет, у меня все то же странное значение.
2. обратите внимание, что
SPDLOG_DEBUG("std::uintmax_t {}, size_t {}", std::numeric_limits<std::uintmax_t>::max(), std::numeric_limits<size_t>::max())
дайте мне одинаковый размер для двух значений :[07/12/2020 12:46:59][debug] std::uintmax_t 18446744073709551615, size_t 18446744073709551615
3. Похоже, это ошибка minGW32 / 64 reddit.com/r/cpp_questions/comments/fina0q /…
Ответ №2:
fs::file_size(filename);
возвращает a std::uintmax_t
. Которое, вероятно, является 64-битным целым числом. Вы присваиваете его a size_t
, которое может (и, вероятно, соответствует вашей ошибке) быть 32-битным целым числом.
Просто используйте uintmax_t
:
uintmax_t filesize;
Комментарии:
1. Это ничего не меняет, у меня все то же странное значение.
2. обратите внимание, что
SPDLOG_DEBUG("std::uintmax_t {}, size_t {}", std::numeric_limits<std::uintmax_t>::max(), std::numeric_limits<size_t>::max())
дайте мне одинаковый размер для двух значений :[07/12/2020 12:46:59][debug] std::uintmax_t 18446744073709551615, size_t 18446744073709551615
Ответ №3:
Это может быть ошибкой MinGW32. Размер, который вы только что получили, является подписанным расширением 3202777528, вы можете проверить это значение самостоятельно:
uint32_t real_file_size = 3202777528u; // roughly 3GB as you said
auto value_you_see = (uint64_t)(int32_t)real_file_size;
Я предполагаю, что MinGW32 использует ssize_t внутренне, что является псевдонимом int32_t в 32-разрядной среде. Возможно, вместо этого вам следует использовать MinGW64.
Ответ №4:
Как говорит Флоран, похоже, это ошибка. gcc 10.2 в Windows использует _wstat, который представляет собой 32-разрядную функцию. Исправление скоро появится в версии 10.3 gcc в Windows.