二进制文件加载导致数据丢失
Binary file loading leading to data loss
我正在尝试从预先格式化的文件中读取数据,以便将其直接传递到顶点缓冲区中。当读取超过一定大小(大于 1152 字节但小于 92,160 字节)的文件时,它会失败。它将一些值从文件写入分配的内存,在不设置其余值之前,留下值 -431602080,这似乎是代表干净内存的 CRT 值(SO Source)。它的值的数量成功写入似乎随文件大小而变化。
我调查过我是否超出了分配限制,但似乎并非如此。我已经检查以确保分配不会因其他原因而失败。我已经将数据读入一个之前填充了值的向量,以查看它是否手动写入值-431602080,但是之前的值仍然表明它只是无法写入内存。
void Mesh::LoadMeshFromFile(DXManager* dxPtr, LPCSTR fileName, int ID)
{
std::fstream f(fileName, std::ios_base::in);
short vertexStride = sizeof(Vertex); //Gets the stride per vertex
long fileLength = f.seekg(0, std::ios::end).tellg(); //Gets the byte count
float vertexCount = (float)fileLength / (float)vertexStride; //Calculates the vertex count
if (vertexCount == (int)vertexCount) //Ensures there are no incomplete vertices
{
if (vertexCount > 134217727 || vertexCount * vertexStride > 2147483647)
{
//Alloc will definitely fail.
//Throw an error
}
else
{
char* vertices = new __nothrow char[(int)fileLength];
if (vertices == NULL)
{
//Allocation failed
//Throw an error
}
else
{
//Read all vertices directly into the array and build the buffer
f.seekg(0, std::ios::beg);
f.read(vertices, fileLength);
BuildBuffer(dxPtr, (Vertex*)vertices, vertexCount);
}
}
}
else
{
//1 or more incomplete vertices.
}
}
下面是一个示例输出。某些文件不会出现此问题,并且似乎与文件大小有关。数据丢失发生的位置不是固定的,而且似乎还因文件大小而异。
如您所见,数据在第 4 个条目之前有效,部分通过该行。
希望有人能够阐明正在发生的事情。
您可以用单精度成功表示的最大连续整数(从零开始计数)float
是 2^24,或 16,777,216。您的文件长度很容易超过 float
可以准确表示的大小。
对整数值使用 long
或 int
,并在需要时类型转换为 float
。反之则不然。
如果您尝试读取比文件中实际存在的字节更多的字节,由于 float
-to-long
中的转换错误 f.read(vertices, fileLength);
,您将无法正确读取数据- 并获得可能的腐败。
我会将您的变量声明为:
long vertexStride = sizeof(Vertex); //Gets the stride per vertex
long fileLength = f.seekg(0, std::ios::end).tellg(); //Gets the byte count
float vertexCount = fileLength / vertexStride; //Calculates the vertex count
此外,如果 seekg
未清除 EOF 标记,请清除文件流。
在查找开始之前使用 f.clear();
。
另外 - 再次 - 你应该从你的所有文件流函数中捕获 return 值......它们可能会失败,你不会停下来检查原因......请参阅此[=中的代码格式21=] 在 SO
由于这是一个二进制文件,您需要指定 ios::binary(fstream 默认为文本)
我正在尝试从预先格式化的文件中读取数据,以便将其直接传递到顶点缓冲区中。当读取超过一定大小(大于 1152 字节但小于 92,160 字节)的文件时,它会失败。它将一些值从文件写入分配的内存,在不设置其余值之前,留下值 -431602080,这似乎是代表干净内存的 CRT 值(SO Source)。它的值的数量成功写入似乎随文件大小而变化。
我调查过我是否超出了分配限制,但似乎并非如此。我已经检查以确保分配不会因其他原因而失败。我已经将数据读入一个之前填充了值的向量,以查看它是否手动写入值-431602080,但是之前的值仍然表明它只是无法写入内存。
void Mesh::LoadMeshFromFile(DXManager* dxPtr, LPCSTR fileName, int ID)
{
std::fstream f(fileName, std::ios_base::in);
short vertexStride = sizeof(Vertex); //Gets the stride per vertex
long fileLength = f.seekg(0, std::ios::end).tellg(); //Gets the byte count
float vertexCount = (float)fileLength / (float)vertexStride; //Calculates the vertex count
if (vertexCount == (int)vertexCount) //Ensures there are no incomplete vertices
{
if (vertexCount > 134217727 || vertexCount * vertexStride > 2147483647)
{
//Alloc will definitely fail.
//Throw an error
}
else
{
char* vertices = new __nothrow char[(int)fileLength];
if (vertices == NULL)
{
//Allocation failed
//Throw an error
}
else
{
//Read all vertices directly into the array and build the buffer
f.seekg(0, std::ios::beg);
f.read(vertices, fileLength);
BuildBuffer(dxPtr, (Vertex*)vertices, vertexCount);
}
}
}
else
{
//1 or more incomplete vertices.
}
}
下面是一个示例输出。某些文件不会出现此问题,并且似乎与文件大小有关。数据丢失发生的位置不是固定的,而且似乎还因文件大小而异。
如您所见,数据在第 4 个条目之前有效,部分通过该行。 希望有人能够阐明正在发生的事情。
您可以用单精度成功表示的最大连续整数(从零开始计数)float
是 2^24,或 16,777,216。您的文件长度很容易超过 float
可以准确表示的大小。
对整数值使用 long
或 int
,并在需要时类型转换为 float
。反之则不然。
如果您尝试读取比文件中实际存在的字节更多的字节,由于 float
-to-long
中的转换错误 f.read(vertices, fileLength);
,您将无法正确读取数据- 并获得可能的腐败。
我会将您的变量声明为:
long vertexStride = sizeof(Vertex); //Gets the stride per vertex
long fileLength = f.seekg(0, std::ios::end).tellg(); //Gets the byte count
float vertexCount = fileLength / vertexStride; //Calculates the vertex count
此外,如果 seekg
未清除 EOF 标记,请清除文件流。
在查找开始之前使用 f.clear();
。
另外 - 再次 - 你应该从你的所有文件流函数中捕获 return 值......它们可能会失败,你不会停下来检查原因......请参阅此[=中的代码格式21=] 在 SO
由于这是一个二进制文件,您需要指定 ios::binary(fstream 默认为文本)