我有一个2mb的文件,其中只包含二进制数据。我只需要将此文件转换为long[]
,同时保持数据在该文件中的顺序。由于在Android上读取文件,因此我只能以InputStream
的形式访问该文件。我迫切想要完成的最后一件事(以及我将数据放入压缩二进制数据格式的原因)是尽可能快地完成。
由于我无法在android上获得File
并且只能使用resource
并将该文件表示为InputStream,我必须为我的桌面编写使用InputStream而不是文件。在我的移动旗舰手机上,使用此代码平均花费了61毫秒:
DataInputStream dis = new DataInputStream(context.getResources().openRawResource(fileID));
int bytesOfBinaryFile = dis.available();
byte[] bytes = new byte[bytesOfBinaryFile];
dis.readFully(bytes);
int longCount = bytesOfBinaryFile / 8;
long[] array = new long[longCount];
bytesToLongArray(bytes, array);
bytesToLongArray(bytes, array)
:
private void bytesToLongArray(byte[] bytes, long[] longs) {
int numberOfLongs = longs.length;
int head = 0;
long l;
for (int i = 0; i < numberOfLongs; i++) {
l = ((bytes[head] & 0xFFL) << 56) |
((bytes[head + 1] & 0xFFL) << 48) |
((bytes[head + 2] & 0xFFL) << 40) |
((bytes[head + 3] & 0xFFL) << 32) |
((bytes[head + 4] & 0xFFL) << 24) |
((bytes[head + 5] & 0xFFL) << 16) |
((bytes[head + 6] & 0xFFL) << 8) |
((bytes[head + 7] & 0xFFL) << 0) ;
longs[i] = l;
head += 8;
}
}
仅供参考和比较,我包含此代码。我把它在我的桌面上运行得非常快(只需要大约3.5毫秒)就可以将2mb文件加载到long[]
:
String fileName = "example";
FileInputStream fip = new FileInputStream(fileName);
FileChannel fc = fip.getChannel();
double bytesOfBinaryFile = fc.size();
int longCount = (int) bytesOfBinaryFile / 8;
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY,
0L, fc.size());
LongBuffer lb = mbb.asLongBuffer();
long[] array = long[longCount];
lb.get(array);
我想知道是否有人知道更快的方式或方法来改进我目前的方法。我希望仍有改进性能的空间。
答案 0 :(得分:1)
这可能就是你要找的东西:
List<Asset> pesonsList= new ArrayList<>();
for (Room room : rooms)
room.getPersonsList().stream()
.filter(person -> person.isTall())
.forEach(person -> {
doSomething(person);
pesonsList.add(person);
});
http://developer.android.com/reference/java/nio/ByteBuffer.html#asLongBuffer%28%29
答案 1 :(得分:1)
也许这个循环会更快:
for(int i=0; i<bytes.length; ++i) {
longs[i >> 3] |= (bytes[i] & 0xFFL) << ((7-(i & 3))<<3);
}
或者如果你想使用不同的字节顺序 - 第一个字节是长的最低 - 而不是这个(减去一个减法操作):
for(int i=0;i<bytes.length;++i) {
longs[i >> 3] |= (bytes[i] & 0xFFL) << ((i & 3)<<3);
}
但请注意,bytes.length必须可被8整除,否则你需要在longs数组中加一个长的。
此外,数组中的longs必须初始化为零。但据我所知,当你分配数组时它会自动完成。