std::filesystem:file_size 给我一个不连贯的值
std::filesystem:file_size send me an incoherent value
为了在我的代码中读取一个文件,我使用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>& 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_error& 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 gigas),我有一个奇怪的问题:
[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) 上没有问题。
有一个错误将在最新版本的 MinGW 中得到纠正。比较:
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::path& p );
fs::file_size(filename);
returns一个std::uintmax_t
。这可能是一个 64 位整数。您将其分配给一个 size_t
,它可能(并且可能会给出您的错误)一个 32 位整数。
只需使用 uintmax_t
:
uintmax_t filesize;
这可能是 MinGW32 的一个错误。你刚刚得到的size是3202777528的signed extension,这个值你可以自己查:
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,这是 32 位环境中 int32_t 的别名。也许你应该改用 MinGW64。
正如 Florent 所说,它似乎是 bug. gcc 10.2 on windows 使用 _wstat 的 32 位函数。即将在 windows.
的 gcc 10.3 版本中进行更正
为了在我的代码中读取一个文件,我使用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>& 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_error& 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 gigas),我有一个奇怪的问题:
[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) 上没有问题。
有一个错误将在最新版本的 MinGW 中得到纠正。比较:
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::path& p );
fs::file_size(filename);
returns一个std::uintmax_t
。这可能是一个 64 位整数。您将其分配给一个 size_t
,它可能(并且可能会给出您的错误)一个 32 位整数。
只需使用 uintmax_t
:
uintmax_t filesize;
这可能是 MinGW32 的一个错误。你刚刚得到的size是3202777528的signed extension,这个值你可以自己查:
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,这是 32 位环境中 int32_t 的别名。也许你应该改用 MinGW64。
正如 Florent 所说,它似乎是 bug. gcc 10.2 on windows 使用 _wstat 的 32 位函数。即将在 windows.
的 gcc 10.3 版本中进行更正