[英]std::filesystem:file_size send me an incoherent value
In order to read a file in my code, I use std::filesystem::file_size ( https://en.cppreference.com/w/cpp/filesystem/file_size ) to get his size.为了在我的代码中读取文件,我使用 std::filesystem::file_size ( https://en.cppreference.com/w/cpp/filesystem/file_size )来获取他的大小。 I use this code:我使用这段代码:
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();
}
This works for most of the files I need to read, but for a file ( ~3 gigas), I have a strange issue:这适用于我需要阅读的大多数文件,但对于一个文件(~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
In the documentation, I can read The non-throwing overload returns static_cast<std::uintmax_t>(-1) on errors.
在文档中,我可以阅读The non-throwing overload returns static_cast<std::uintmax_t>(-1) on errors.
. . But the value 18446744072617361848 is different from static_cast<std::uintmax_t>(-1)
, so I am lost....但是值 18446744072617361848 与static_cast<std::uintmax_t>(-1)
不同,所以我迷路了....
My compiler is mingw32:我的编译器是 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.
I don't have the issue on linux (gcc).我在 linux (gcc) 上没有问题。
There is a bug that will be corrected in recent versions of MinGW.在最近版本的 MinGW 中有一个错误将得到纠正。 cf:参考:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95749 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95749
But event that, should replace但是,应该替换的事件
size_t filesize;
by经过
std::uintmax_t filesize;
according the function's signature:根据函数的签名:
std::uintmax_t file_size( const std::filesystem::path& p );
fs::file_size(filename);
returns a std::uintmax_t
.返回一个std::uintmax_t
。 Which is probably a 64bit integer.这可能是一个 64 位 integer。 You assign that to a size_t
which maybe (and probably is given your error) a 32 bit integer.您将其分配给一个size_t
,它可能(并且可能会给出您的错误)一个 32 位 integer。
Just use a uintmax_t
:只需使用uintmax_t
:
uintmax_t filesize;
This may be a bug of MinGW32.这可能是 MinGW32 的一个错误。 The size you just got is a signed extension of 3202777528, you can check this value by yourself:刚刚得到的size是3202777528的签名扩展,这个值可以自己查:
uint32_t real_file_size = 3202777528u; // roughly 3GB as you said
auto value_you_see = (uint64_t)(int32_t)real_file_size;
My guess is that MinGW32 uses ssize_t internally, which is an alias to int32_t in a 32-bits environment.我的猜测是 MinGW32 在内部使用 ssize_t ,这是 32 位环境中 int32_t 的别名。 Maybe you should use MinGW64 instead.也许您应该改用 MinGW64。
Like says by Florent, it seems to be a bug .正如 Florent 所说,这似乎是一个错误。 gcc 10.2 on windows use _wstat which is a 32 bits function. windows 上的 gcc 10.2使用 _wstat,它是一个 32 位 function。 The correction will coming soon, in the version 10.3 of gcc on windows.在 windows 上的 gcc 的 10.3 版本中即将进行更正。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.