读书人

文件传输的几种形式效率比较

发布时间: 2012-12-24 10:43:14 作者: rapoo

文件传输的几种方式效率比较

package com.yonge.nio;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;/** * 文件传输几种方式比较 * @author wb-gaoy * @version $Id: ChannelTest.java,v 0.1 2012-12-13 下午7:28:40 wb-gaoy Exp $ */public class ChannelTest {    public boolean copyFileByIO(File srcFile, File targetDir) throws IOException {        FileInputStream fis = new FileInputStream(srcFile);        FileOutputStream fos = new FileOutputStream(targetDir + File.separator + srcFile.getName());        byte[] bytes = new byte[1024 * 1024];        int length = -1;        while ((length = fis.read(bytes)) != -1) {            fos.write(bytes, 0, length);        }        fis.close();        fos.close();        return true;    }    public boolean copyFileByNIO(File srcFile, File targetDir) throws IOException {        FileInputStream fis = new FileInputStream(srcFile);        FileOutputStream fos = new FileOutputStream(targetDir + File.separator + srcFile.getName());        try {            FileChannel fisChannel = fis.getChannel();            FileChannel fosChannel = fos.getChannel();            ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024);            while (fisChannel.read(byteBuffer) != -1) {                byteBuffer.flip();                fosChannel.write(byteBuffer);                byteBuffer.clear();            }            fosChannel.close();            fisChannel.close();        } finally {            fis.close();            fos.close();        }        return true;    }    public boolean copyFileByTransfer(File srcFile, File targetDir) throws IOException {        FileInputStream fis = new FileInputStream(srcFile);        FileOutputStream fos = new FileOutputStream(targetDir + File.separator + srcFile.getName());        try {            FileChannel fisChannel = fis.getChannel();            FileChannel fosChannel = fos.getChannel();            fisChannel.transferTo(0, fisChannel.size(), fosChannel);            fosChannel.close();            fisChannel.close();        } finally {            fis.close();            fos.close();        }        return true;    }    //注意:如果目标文件已经存在或磁盘间的格式不一样(例如源文件磁盘是ntfs,而目标磁盘是fat32),则不会成功    public boolean moveFile(File srcFile, File targetFile) {        srcFile.renameTo(new File(targetFile + File.separator + srcFile.getName()));        return true;    }    /**     * @param args     */    public static void main(String[] args) {        final ChannelTest test = new ChannelTest();        final File targetDir = new File("e:/temp");        Thread thread1 = new Thread(new Runnable() {            @Override            public void run() {                try {                    long start = System.currentTimeMillis();                    test.copyFileByIO(new File("e:/ppl20120921145445000611.rar"), targetDir);                    System.out.println("IO cost:" + (System.currentTimeMillis() - start) + "ms");                } catch (IOException e) {                    e.printStackTrace();                }            }        }, "A");        thread1.start();        Thread thread2 = new Thread(new Runnable() {            @Override            public void run() {                try {                    long start = System.currentTimeMillis();                    test.copyFileByNIO(new File("e:/ppl20120921145445000612.rar"), targetDir);                    System.out.println("NIO cost:" + (System.currentTimeMillis() - start) + "ms");                } catch (IOException e) {                    e.printStackTrace();                }            }        }, "B");        thread2.start();        Thread thread3 = new Thread(new Runnable() {            @Override            public void run() {                long start = System.currentTimeMillis();                test.moveFile(new File("e:/ppl20120921145445000613.rar"), targetDir);                System.out.println("Move cost:" + (System.currentTimeMillis() - start) + "ms");            }        }, "C");        thread3.start();        Thread thread4 = new Thread(new Runnable() {            @Override            public void run() {                long start = System.currentTimeMillis();                try {                    test.copyFileByTransfer(new File("e:/ppl20120921145445000614.rar"), targetDir);                } catch (IOException e) {                    e.printStackTrace();                }                System.out.println("Transfer cost:" + (System.currentTimeMillis() - start) + "ms");            }        }, "D");        thread4.start();    }}

?上面是四种文件传输方式,测试结果是transfer的效率最低,而网上都说这种效率高,不知道是什么原因,欢迎大家测试一下,说说各自的想法。

1 楼 xiaoZ5919 2012-12-14 我测试了一下。首先我觉得你这样测试有点科学! 不应该用线程来同时进行,即便是测试的是IO,也不能保证分给每个线程的时间片是一样的。我测试了结果如下:
文件大小为3.4M
第一次用transferTo 花了235m
再一次IO 花了29ms
我觉得有可能是因为缓存的原因所以又用transferTo试了一次
基本在20ms,又试了一次IO也基本在20ms。
估计是文件比较小,transferTo的优势不明显。
我用netty写过了文件传输的东东,客户端用的transferTo,服务端还是用的buffer + fileoutstream。传输这个3.4m的文件1000次,客户端一次minor gc都没有。然而服务端gc很多 2 楼 yonge812 2012-12-15 xiaoZ5919 写道我测试了一下。首先我觉得你这样测试有点科学! 不应该用线程来同时进行,即便是测试的是IO,也不能保证分给每个线程的时间片是一样的。我测试了结果如下:
文件大小为3.4M
第一次用transferTo 花了235m
再一次IO 花了29ms
我觉得有可能是因为缓存的原因所以又用transferTo试了一次
基本在20ms,又试了一次IO也基本在20ms。
估计是文件比较小,transferTo的优势不明显。
我用netty写过了文件传输的东东,客户端用的transferTo,服务端还是用的buffer + fileoutstream。传输这个3.4m的文件1000次,客户端一次minor gc都没有。然而服务端gc很多
我也对单个方法执行测试了的,确实transferTo是最慢的,文件的大小从几十k到几百M都试过,答案一样的,如果是服务员与客户端通信,可能不一样吧,没试过 3 楼 xiaoZ5919 2012-12-15 yonge812 写道xiaoZ5919 写道我测试了一下。首先我觉得你这样测试有点科学! 不应该用线程来同时进行,即便是测试的是IO,也不能保证分给每个线程的时间片是一样的。我测试了结果如下:
文件大小为3.4M
第一次用transferTo 花了235m
再一次IO 花了29ms
我觉得有可能是因为缓存的原因所以又用transferTo试了一次
基本在20ms,又试了一次IO也基本在20ms。
估计是文件比较小,transferTo的优势不明显。
我用netty写过了文件传输的东东,客户端用的transferTo,服务端还是用的buffer + fileoutstream。传输这个3.4m的文件1000次,客户端一次minor gc都没有。然而服务端gc很多
我也对单个方法执行测试了的,确实transferTo是最慢的,文件的大小从几十k到几百M都试过,答案一样的,如果是服务员与客户端通信,可能不一样吧,没试过
确实是慢! 谢谢你的测试,我猜测transferTo在内核态完成,使用到内存分配是由系统来完成的。而且jvm的内存是事先分配好的。 4 楼 canghailan 2012-12-17 transferTo在传输速度上可能没有什么优势,毕竟到底层都是磁盘IO,但是在资源消耗上(CPU,内存)可能要好。
http://java--hhf.iteye.com/blog/1747507#comments8楼中写了我的一些看法。

读书人网 >行业软件

热点推荐