首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Java与C++中读取二进制文件

在Java与C++中读取二进制文件
EN

Stack Overflow用户
提问于 2011-08-08 04:41:13
回答 6查看 3.7K关注 0票数 7

我有一个二进制文件(大约100兆字节),我需要快速读入。在C++中,我可以将文件加载到一个字符指针中,并通过递增指针来遍历它。这当然是非常快的。

在Java中有没有更快的方法来做到这一点?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-08-08 15:13:58

如果您使用内存映射文件或常规缓冲区,您将能够以硬件允许的速度读取数据。

代码语言:javascript
运行
复制
File tmp = File.createTempFile("deleteme", "bin");
tmp.deleteOnExit();
int size = 1024 * 1024 * 1024;

long start0 = System.nanoTime();
FileChannel fc0 = new FileOutputStream(tmp).getChannel();
ByteBuffer bb = ByteBuffer.allocateDirect(32 * 1024).order(ByteOrder.nativeOrder());

for (int i = 0; i < size; i += bb.capacity()) {
    fc0.write(bb);
    bb.clear();
}
long time0 = System.nanoTime() - start0;
System.out.printf("Took %.3f ms to write %,d MB using ByteBuffer%n", time0 / 1e6, size / 1024 / 1024);

long start = System.nanoTime();
FileChannel fc = new FileInputStream(tmp).getChannel();
MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, size);
LongBuffer longBuffer = buffer.order(ByteOrder.nativeOrder()).asLongBuffer();
long total = 0; // used to prevent a micro-optimisation.
while (longBuffer.remaining() > 0)
    total += longBuffer.get();
fc.close();
long time = System.nanoTime() - start;
System.out.printf("Took %.3f ms to read %,d MB MemoryMappedFile%n", time / 1e6, size / 1024 / 1024);

long start2 = System.nanoTime();
FileChannel fc2 = new FileInputStream(tmp).getChannel();
bb.clear();
while (fc2.read(bb) > 0) {
    while (bb.remaining() > 0)
        total += bb.get();
    bb.clear();
}
fc2.close();
long time2 = System.nanoTime() - start2;
System.out.printf("Took %.3f ms to read %,d MB File via NIO%n", time2 / 1e6, size / 1024 / 1024);

打印

代码语言:javascript
运行
复制
Took 305.243 ms to write 1,024 MB using ByteBuffer
Took 286.404 ms to read 1,024 MB MemoryMappedFile
Took 155.598 ms to read 1,024 MB File via NIO

这是针对一个比你想要的文件大10倍的文件。它这么快是因为数据被缓存在内存中(我有一个SSD驱动器)。如果你有快速的硬件,那么读取数据的速度就会很快。

票数 8
EN

Stack Overflow用户

发布于 2011-08-08 04:47:23

当然,您可以使用内存映射文件。

以下是示例代码的两个很好的链接:

  • Thinking in Java: Memory-mapped files
  • Java Tips: How to create a memory-mapped file

如果您不想走这条路,只需使用普通的InputStream (例如将其包装在BufferedInputStream中之后的DataInputStream

票数 6
EN

Stack Overflow用户

发布于 2011-08-08 04:55:34

大多数文件不需要内存映射,而是可以通过标准Java I/O读取,特别是在文件非常小的情况下。读取所述文件的一种合理方式是使用BufferedInputStream。

代码语言:javascript
运行
复制
InputStream in = new BufferedInputStream(new FileInputStream("somefile.ext"));

缓冲已经在Java中针对大多数计算机进行了优化。如果你有一个更大的文件,比如说100MB,那么你会考虑进一步优化它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6975658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档