我使用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]
我的代码出了什么问题?
答案 0 :(得分:2)
您遇到字节顺序问题。二进制文件中的72057594037927936
为0x0100000000000000
,144115188075855872
为0x0200000000000000
等。
Java正在以大端顺序(最重要的字节优先)将long
写入缓冲区,而Python则以小端顺序(最低有效字节优先)解释生成的字节流。
一个简单的解决方法是更改Java缓冲区的ByteOrder
属性:
mem.order(ByteOrder.LITTLE_ENDIAN);
或者告诉Python使用big-endian命令。 Python似乎没有为其memmap函数提供类似选项,因此可能需要使用struct.unpack_from
来指定字节顺序。