C++ 将原始编码的nrrd数据文件读入双精度
有人知道如何读取原始编码的文件吗?如此难堪。。。。我想我是在读浮点数或双数。这件事我已经坚持了好几个星期了。谢谢大家! 我试图从中读取的文件: 原始编码说明: hello://teem.sourceforge.net/nrrd/format.html#encoding (将hello更改为http以转到第页) -“原始”-数据在磁盘上的显示方式与内存中的显示方式完全相同,即字节值和字节顺序。由write()和fwrite()生成,适用于read()或fread() 文件信息: -我认为这里唯一重要的是big-endian(仍在试图理解谷歌的意思)和原始编码 我目前的方法不确定是否正确:C++ 将原始编码的nrrd数据文件读入双精度,c++,file-io,data-visualization,vtk,scivis,C++,File Io,Data Visualization,Vtk,Scivis,有人知道如何读取原始编码的文件吗?如此难堪。。。。我想我是在读浮点数或双数。这件事我已经坚持了好几个星期了。谢谢大家! 我试图从中读取的文件: 原始编码说明: hello://teem.sourceforge.net/nrrd/format.html#encoding (将hello更改为http以转到第页) -“原始”-数据在磁盘上的显示方式与内存中的显示方式完全相同,即字节值和字节顺序。由write()和fwrite()生成,适用于read()或fread() 文件信息: -我认为这里唯一
//Function ripped off from example of c++ ifstream::read reference page
void scantensor(string filename){
ifstream tdata(filename, ifstream::binary); // not sure if I should put ifstream::binary here
// other things I tried
// ifstream tdata(filename) ifstream tdata(filename, ios::in)
if(tdata){
tdata.seekg(0, tdata.end);
int length = tdata.tellg();
tdata.seekg(0, tdata.beg);
char* buffer = new char[length];
tdata.read(buffer, length);
tdata.close();
double* d;
d = (double*) buffer;
} else cerr << "failed" << endl;
}
/* P.S. I attempted to print the first 100 elements of the array.
Then I print 100 other elements at some arbitrary array indices (i.e. 9,900 - 10,000). I actually kept increasing the number of 0's until I ran out of bound at 100,000,000 (I don't think that's how it works lol but I was just playing around to see what happens)
Here's the part that makes me suspicious: so the ifstream different has different constructors like the ones I tried above.
the first 100 values are always the same.
if I use ifstream::binary, then I get some values for the 100 arbitrary printing
if I use the other two options, then I get -6.27744e+066 for all 100 of them
So for now I am going to assume that ifstream::binary is the correct one. The thing is, I am not sure if the file I provided is how binary files actually look like. I am also unsure if these are the actual numbers that I am supposed to read in or just casting gone wrong. I do realize that my casting from char* to double* can be unsafe, and I got that from one of the threads.
*/
我目前正在从文件中解析的浮动非常大(即-4.68855e-229,-1.32351e+120)
也许有人知道如何从Paraview中提取浮点数?因为您想使用Double,我建议将文件中的数据作为Double的缓冲区读取:
const long machineMemory = 0x40000000; // 1 GB
FILE* file = fopen("c:\\data.bin", "rb");
if (file)
{
int size = machineMemory / sizeof(double);
if (size > 0)
{
double* data = new double[size];
int read(0);
while (read = fread(data, sizeof(double), size, file))
{
// Process data here (read = number of doubles)
}
delete [] data;
}
fclose(file);
}
我尝试了它,结果与使用ifstream和ifstream::binary得到的结果相同。谢谢仍然需要更多的答案来验证,但到目前为止它似乎是正确的。char的大小是1字节。double的大小是8字节。这实际上取决于操作系统,但您可以通过调用sizeof(char)和sizeof(double)轻松检查这一点。因此,当你处理双倍时,你需要考虑两件事:1)字节排序2)位在一个字节(大字节或小字节)内排序。如果你能提出更具体的问题,我可以给你举一些具体的例子。所以我问了我的教授,似乎这是不正确的。因为与Paraview中生成的数据相比,数据范围非常大。我不确定我的问题有多具体,因为我不太习惯这种类型的文件。如果文件的大小非常大,那么是的,建议的解决方案将导致OutOfMemory异常,程序将崩溃。假设文件为1TB,计算机内存为4GB。显然,1TB不能与4GB兼容。要解决这个问题,我们需要读取一块数据,处理它,然后读取另一个卡盘,直到到达文件的末尾。现在它可以用于任何大小的文件。您只需要确定机器上的可用内存并将其分配给machineMemory。
const long machineMemory = 0x40000000; // 1 GB
FILE* file = fopen("c:\\data.bin", "rb");
if (file)
{
int size = machineMemory / sizeof(double);
if (size > 0)
{
double* data = new double[size];
int read(0);
while (read = fread(data, sizeof(double), size, file))
{
// Process data here (read = number of doubles)
}
delete [] data;
}
fclose(file);
}