数组和文件大小的数据类型
Data type for size of arrays and files
我应该使用什么数据类型来定义文件大小以将文件数据存储在动态数组中?考虑以下代码段:
#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) 给出警告:'initializing': conversion from 'file_size_t' to 'unsigned int', possible loss of data
在为 32 位架构构建时。我使用 uint64_t
是因为它与接收的 tellg
和 seekg
或 return streamsize
等流函数兼容(定义为 using streamoff = long long;
iosfwd.h
) 和等效类型。
如何定义 file_size_t
以移除此警告?使用 streamsize
也会给出我在评论中指出的警告。
size_t
是 sizeof()
返回的传统类型,指定某个对象的大小,可以是数组,也可以是单个对象。
您的数据来自文件这一事实无关紧要。它仍然以数组形式结束,size_t
是给定数组的所谓大小的类型。
您的操作系统完全有可能允许创建大于 size_t
可以表示的值范围的文件。据推测,如果您希望将这样的文件读入阵列,由于操作系统的限制,您将无法读取其全部内容。你显然有一些方法来处理这种情况,但在所有情况下 size_t
总是 size_t
.
您无法修复该警告,因为它表明您的代码存在一个简单的缺陷。在 32 位系统上,您仍然可以拥有超过 32 位整数范围的文件大小。你必须处理这个案子。
所以,简而言之,需要以下步骤:
- 找到文件的大小。这将使用任何类型来表示相应系统的文件大小。
- 然后,检查您是否可以将其放入您的内存中 space,即它是否可以存储在
size_t
中。我建议使用一个简单的 static_cast
来转换值,并使用一个简单的 static_cast
返回以转换为以前的值,以确保它不会丢失任何信息。确保您不会被有符号整数扩展语义绊倒!
- 然后,使用该大小分配相应的内存量。使用
new
是一种(不好的)方法,但它主要有效。
- 最后,从流中读取之前确定的数据量。请注意,文件的大小可以大于或小于您最初确定的大小,因为写入它可以同时发生。考虑发生这种情况时您想做什么以及如何检测它。
顺便说一句:根据文件的大小和你想用它做什么,最简单的方法可能是只对它进行内存映射。特别是简单的只读访问既简单又比复制数据快得多。我认为 C++ 没有为此提供内置库,因此您可能必须在此处编写特定于 OS 的代码。使用现有代码作为后备,这应该相对简单。
我应该使用什么数据类型来定义文件大小以将文件数据存储在动态数组中?考虑以下代码段:
#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) 给出警告:'initializing': conversion from 'file_size_t' to 'unsigned int', possible loss of data
在为 32 位架构构建时。我使用 uint64_t
是因为它与接收的 tellg
和 seekg
或 return streamsize
等流函数兼容(定义为 using streamoff = long long;
iosfwd.h
) 和等效类型。
如何定义 file_size_t
以移除此警告?使用 streamsize
也会给出我在评论中指出的警告。
size_t
是 sizeof()
返回的传统类型,指定某个对象的大小,可以是数组,也可以是单个对象。
您的数据来自文件这一事实无关紧要。它仍然以数组形式结束,size_t
是给定数组的所谓大小的类型。
您的操作系统完全有可能允许创建大于 size_t
可以表示的值范围的文件。据推测,如果您希望将这样的文件读入阵列,由于操作系统的限制,您将无法读取其全部内容。你显然有一些方法来处理这种情况,但在所有情况下 size_t
总是 size_t
.
您无法修复该警告,因为它表明您的代码存在一个简单的缺陷。在 32 位系统上,您仍然可以拥有超过 32 位整数范围的文件大小。你必须处理这个案子。
所以,简而言之,需要以下步骤:
- 找到文件的大小。这将使用任何类型来表示相应系统的文件大小。
- 然后,检查您是否可以将其放入您的内存中 space,即它是否可以存储在
size_t
中。我建议使用一个简单的static_cast
来转换值,并使用一个简单的static_cast
返回以转换为以前的值,以确保它不会丢失任何信息。确保您不会被有符号整数扩展语义绊倒! - 然后,使用该大小分配相应的内存量。使用
new
是一种(不好的)方法,但它主要有效。 - 最后,从流中读取之前确定的数据量。请注意,文件的大小可以大于或小于您最初确定的大小,因为写入它可以同时发生。考虑发生这种情况时您想做什么以及如何检测它。
顺便说一句:根据文件的大小和你想用它做什么,最简单的方法可能是只对它进行内存映射。特别是简单的只读访问既简单又比复制数据快得多。我认为 C++ 没有为此提供内置库,因此您可能必须在此处编写特定于 OS 的代码。使用现有代码作为后备,这应该相对简单。