C++ 将原始编码的nrrd数据文件读入双精度

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() 文件信息: -我认为这里唯一

有人知道如何读取原始编码的文件吗?如此难堪。。。。我想我是在读浮点数或双数。这件事我已经坚持了好几个星期了。谢谢大家!

我试图从中读取的文件:

原始编码说明: hello://teem.sourceforge.net/nrrd/format.html#encoding (将hello更改为http以转到第页) -“原始”-数据在磁盘上的显示方式与内存中的显示方式完全相同,即字节值和字节顺序。由write()和fwrite()生成,适用于read()或fread()

文件信息: -我认为这里唯一重要的是big-endian(仍在试图理解谷歌的意思)和原始编码

我目前的方法不确定是否正确:

 //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);
}