【问题标题】:Is this a good way of reading a binary file full of doubles?这是读取充满双打的二进制文件的好方法吗?
【发布时间】:2017-11-12 09:34:48
【问题描述】:

我有一个需要读取然后存储到变量的二进制文件列表。每个文件都是大量双打的集合。这些文件是用linux下的C语言中的双重类型的C程序保存的。现在,我想使用 Java 读取所有这些文件。这是您可以实现的最快方法吗?在我的 PC 中,读取 10 个文件(1.5 Mb/文件和 194,672 个双精度/文件)需要 24 秒并将它们存储到一个数组中。我正在考虑使用某种类型的缓冲区,但我不确定是否应该从乞讨中留下一些字节......

    int i;
    int num_f = 10;
    int num_d = 194672;

    File folder = new File(route);
    File[] listOfFiles = folder.listFiles();

    float double_list[][] = new float[num_f][num_d];

    for (int file = 0; file < listOfFiles.length; file++) {
        if (listOfFiles[file].isFile()) {
            try{
                br = new DataInputStream(new FileInputStream(listOfFiles[file].getAbsolutePath()));
                //We read all file 
                i = 0;
                while(br.available() > 0) {
                    //I know that float != double but I don't think I will lose a huge precision 
                    //as the double numbers stored are in a region [-5,5] and with this way I reduce 
                    //the amount of memory needed. (float) is not cpu consuming (<1s).
                    double_list[file][i++] = (float) br.readDouble();
                }

                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try {
                    //Close file
                    br.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
     }

【问题讨论】:

  • 您应该在DataInputStreamFileInputStream 之间添加一个BufferedInputStream。默认缓冲区大小应该不错,但您可以随时尝试。
  • 使用DataInputStream你不能控制endianness。如果您的代码不起作用,可能是因为这个原因,因此您可能需要改用DoubleBuffer
  • 好的,现在使用 buferedinputstream 需要 7 秒,减少了 70%。好的!没有什么可以改进的了?顺便说一句,我该如何使用 DoubleBuffer?
  • 如果你的内存数组是double,而不是float,那么你可以尝试使用DoubleBuffer,将10个8 * num_d = 1557376字节块读入byte[],然后使用ByteBuffer.wrap(bytes).asDoubleBuffer().get(double_list[i])。这种块读取可能会更快。

标签: java file binary


【解决方案1】:

最后,我可以在 Andreas 和这个网站 (http://pulasthisupun.blogspot.com.es/2016/06/reading-and-writing-binary-files-in.html) 的帮助下做到这一点(查看其他类型格式!)。对于字节序,默认选项是 BIG_ENDIAN 代码,但我有无意义的东西作为无穷大的数字。尽管如此,使用 LITTLE_ENDIAN 我得到了正确的数字!尽管如此,我将来还是需要做一些测试,以确保我不必从一开始就让一些额外的字节......

顺便说一句,花费的时间:0.160048575s,还不错;)

int i;
int num_f = 10;
int num_d = 194672;

File folder = new File(route);
File[] listOfFiles = folder.listFiles();

float double_list[][] = new float[num_f][num_d];

for (int file = 0; file < listOfFiles.length; file++) {
    if (listOfFiles[file].isFile()) {
        try{
           fc = (FileChannel) Files.newByteChannel(Paths.get(listOfFiles[file].getAbsolutePath()), StandardOpenOption.READ);
           byteBuffer = ByteBuffer.allocate((int)fc.size());
           byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
           fc.read(byteBuffer);
           byteBuffer.flip();

           buffer = byteBuffer.asDoubleBuffer();
           ((DoubleBuffer)buffer).get(double_list[file]);
           byteBuffer.clear();

           fc.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //Close file
                br.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    相关资源
    最近更新 更多