无法使用Python读取在Java中创建的二进制文件

时间:2018-06-16 15:46:40

标签: java python memory mapping binary-data

我使用Java和内存映射创建了一个二进制文件。它包含一个1到1千万的整数列表:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class MemoryMapWriter {

 public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException {
  File f = new File("file.bin");
  f.delete();

  FileChannel fc = new RandomAccessFile(f, "rw").getChannel();

  long bufferSize=64*1000;
  MappedByteBuffer mem =fc.map(FileChannel.MapMode.READ_WRITE, 0, bufferSize);

  int start = 0;
  long counter=1;
  long HUNDREDK=100000;
  long startT = System.currentTimeMillis();
  long noOfMessage = HUNDREDK * 10 * 10; 
  for(;;)
  {         
   if(!mem.hasRemaining())
   {
    start+=mem.position();
    mem =fc.map(FileChannel.MapMode.READ_WRITE, start, bufferSize);
   }
   mem.putLong(counter); 
   counter++;
   if(counter > noOfMessage )
    break; 
  }
  long endT = System.currentTimeMillis();
  long tot = endT - startT;
  System.out.println(String.format("No Of Message %s , Time(ms) %s ",noOfMessage, tot)) ;  
 }

然后我尝试使用Python和内存映射来阅读它:

import pandas as pd
import numpy as np
import os
import shutil
import re
import mmap

a=np.memmap("file.bin",mode='r',dtype='int64')
print(a[0:9])

但打印前十个元素,这就是结果:

[ 72057594037927936, 144115188075855872, 216172782113783808,
  288230376151711744, 360287970189639680, 432345564227567616,
  504403158265495552, 576460752303423488, 648518346341351424,
  720575940379279360]

我的代码出了什么问题?

1 个答案:

答案 0 :(得分:2)

您遇到字节顺序问题。二进制文件中的720575940379279360x01000000000000001441151880758558720x0200000000000000等。

Java正在以大端顺序(最重要的字节优先)将long写入缓冲区,而Python则以小端顺序(最低有效字节优先)解释生成的字节流。

一个简单的解决方法是更改​​Java缓冲区的ByteOrder属性:

mem.order(ByteOrder.LITTLE_ENDIAN);

或者告诉Python使用big-endian命令。 Python似乎没有为其memmap函数提供类似选项,因此可能需要使用struct.unpack_from来指定字节顺序。