java filechannel 性能,Java NIO FileChannel与FileOutputstream的性能/实用性

I am trying to figure out if there is any difference in performance (or advantages) when we use nio FileChannel versus normal FileInputStream/FileOuputStream to read and write files to filesystem. I observed that on my machine both perform at the same level, also many times the FileChannel way is slower. Can I please know more details comparing these two methods. Here is the code I used, the file that I am testing with is around 350MB. Is it a good option to use NIO based classes for File I/O, if I am not looking at random access or other such advanced features?

package trialjavaprograms;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

public class JavaNIOTest {

public static void main(String[] args) throws Exception {

useNormalIO();

useFileChannel();

}

private static void useNormalIO() throws Exception {

File file = new File("/home/developer/test.iso");

File oFile = new File("/home/developer/test2");

long time1 = System.currentTimeMillis();

InputStream is = new FileInputStream(file);

FileOutputStream fos = new FileOutputStream(oFile);

byte[] buf = new byte[64 * 1024];

int len = 0;

while((len = is.read(buf)) != -1) {

fos.write(buf, 0, len);

}

fos.flush();

fos.close();

is.close();

long time2 = System.currentTimeMillis();

System.out.println("Time taken: "+(time2-time1)+" ms");

}

private static void useFileChannel() throws Exception {

File file = new File("/home/developer/test.iso");

File oFile = new File("/home/developer/test2");

long time1 = System.currentTimeMillis();

FileInputStream is = new FileInputStream(file);

FileOutputStream fos = new FileOutputStream(oFile);

FileChannel f = is.getChannel();

FileChannel f2 = fos.getChannel();

ByteBuffer buf = ByteBuffer.allocateDirect(64 * 1024);

long len = 0;

while((len = f.read(buf)) != -1) {

buf.flip();

f2.write(buf);

buf.clear();

}

f2.close();

f.close();

long time2 = System.currentTimeMillis();

System.out.println("Time taken: "+(time2-time1)+" ms");

}

}

解决方案

My experience with larger files sizes has been that java.nio is faster than java.io. Solidly faster. Like in the >250% range. That said, I am eliminating obvious bottlenecks, which I suggest your micro-benchmark might suffer from. Potential areas for investigating:

The buffer size. The algorithm you basically have is

copy from disk to buffer

copy from buffer to disk

My own experience has been that this buffer size is ripe for tuning. I've settled on 4KB for one part of my application, 256KB for another. I suspect your code is suffering with such a large buffer. Run some benchmarks with buffers of 1KB, 2KB, 4KB, 8KB, 16KB, 32KB and 64KB to prove it to yourself.

Don't perform java benchmarks that read and write to the same disk.

If you do, then you are really benchmarking the disk, and not Java. I would also suggest that if your CPU is not busy, then you are probably experiencing some other bottleneck.

Don't use a buffer if you don't need to.

Why copy to memory if your target is another disk or a NIC? With larger files, the latency incured is non-trivial.

Like other have said, use FileChannel.transferTo() or FileChannel.transferFrom(). The key advantage here is that the JVM uses the OS's access to DMA (Direct Memory Access), if present. (This is implementation dependent, but modern Sun and IBM versions on general purpose CPUs are good to go.) What happens is the data goes straight to/from disc, to the bus, and then to the destination... bypassing any circuit through RAM or the CPU.

The web app I spent my days and night working on is very IO heavy. I've done micro benchmarks and real-world benchmarks too. And the results are up on my blog, have a look-see:

Use production data and environments

Micro-benchmarks are prone to distortion. If you can, make the effort to gather data from exactly what you plan to do, with the load you expect, on the hardware you expect.

My benchmarks are solid and reliable because they took place on a production system, a beefy system, a system under load, gathered in logs. Not my notebook's 7200 RPM 2.5" SATA drive while I watched intensely as the JVM work my hard disc.

What are you running on? It matters.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值