0

为了在我的代码中读取文件,我使用 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) 上没有这个问题。

4

4 回答 4

1

在最近版本的 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 );
于 2020-12-07T11:27:08.713 回答
0

fs::file_size(filename);返回一个std::uintmax_t。这可能是一个 64 位整数。您将其分配给size_t可能(并且可能会给出您的错误)一个 32 位整数。

只需使用uintmax_t

uintmax_t filesize;

于 2020-12-07T11:27:19.280 回答
0

这可能是 MinGW32 的一个错误。刚刚得到的size是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 ,这是 32 位环境中 int32_t 的别名。也许您应该改用 MinGW64。

于 2020-12-07T12:00:59.863 回答
0

正如 Florent 所说,这似乎是一个错误Windows 上的 gcc 10.2使用 _wstat 这是一个 32 位函数。在 windows 上的 gcc 版本 10.3 中将很快进行更正。

于 2020-12-08T10:31:21.513 回答