我应该使用哪种数据类型来定义文件大小以在动态数组中存储文件数据?请考虑以下代码段:
#include <cstdint>
#include <string>
#include <fstream>
typedef uint64_t file_size_t;
typedef uint64_t file_pos_t;
int32_t ReadBytes(const std::wstring& file, file_pos_t pos, file_size_t numBytes, char*& readDataBuffer,
file_size_t& bufferLen)
{
using namespace std;
bufferLen = 0;
readDataBuffer = nullptr;
ifstream is(file, ifstream::binary);
if (!is)
return -1;
is.seekg(pos);
if (!is)
{
is.close();
return -2;
}
// Compiler warning in the following code line:
readDataBuffer = new char[numBytes]();
is.read(readDataBuffer, numBytes);
bufferLen = is.gcount();
is.close();
return 0;
}
使用我已定义的类型,我的编译器(MS Visual C ++ 2017)在构建32位体系结构时发出警告:'initializing': conversion from 'file_size_t' to 'unsigned int', possible loss of data
。我使用了uint64_t
,因为它与tellg
和seekg
等流功能兼容,可以接收或返回streamsize
(在{{1}中定义为using streamoff = long long;
})和等效类型。
如何定义删除此警告的iosfwd.h
?使用file_size_t
也会给出我在评论中指出的警告。
答案 0 :(得分:2)
size_t
是由sizeof()
返回的传统类型,它指定某个对象的大小,可以是数组,也可以是单个对象。
您的数据来自文件这一事实无关紧要。它仍然以数组结尾,size_t
是指定数组所谓大小的类型。
您的操作系统完全有可能允许创建大于size_t
可以表示的值范围的文件。据推测,如果您希望将此类文件读入阵列,则由于操作系统的限制,您将无法读取其全部内容。您显然会有一些处理这种情况的方法,但在所有情况下,size_t
始终为size_t
。
答案 1 :(得分:1)
您无法修复该警告,因为它会在您的代码中展示一个简单的缺陷。在32位系统上,您仍然可以使文件大小超过32位整数的范围。你必须处理这个案子。
因此,简而言之,以下步骤是必要的:
size_t
中。我建议使用简单的static_cast
来转换价值,然后将简单的static_cast
转换回原值,以确保它不会丢失任何信息。确保您不会超过有符号整数扩展语义!new
是一种(不好)方式,但它主要起作用。顺便说一句:根据文件的大小以及你想用它做什么,最简单的方法就是内存映射它。特别是简单的只读访问既简单又快于复制数据。我不认为C ++附带了内置库,因此您可能必须在此处编写特定于操作系统的代码。使用现有代码作为后备,但这应该是相对简单的。