`

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

阅读更多
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的效率最低,而网上都说这种效率高,不知道是什么原因,欢迎大家测试一下,说说各自的想法。

0
0
分享到:
评论
4 楼 canghailan 2012-12-17  
transferTo在传输速度上可能没有什么优势,毕竟到底层都是磁盘IO,但是在资源消耗上(CPU,内存)可能要好。
http://java--hhf.iteye.com/blog/1747507#comments8楼中写了我的一些看法。
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的内存是事先分配好的。
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都试过,答案一样的,如果是服务员与客户端通信,可能不一样吧,没试过
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很多

相关推荐

    下载文件的几种方式

    本文将详细介绍几种常见的下载文件方式。 1. **直接点击下载** 这是最基本的下载方式,通常在网页上,我们点击一个链接或按钮,浏览器会自动开始下载文件。例如,`xiazai.aspx`可能是一个网页,用户可以直接点击...

    解析XML文件的四种方式整合

    XML(eXtensible Markup Language)是一种用于存储和传输数据的标记语言,广泛应用于Web应用程序、数据交换和配置文件等领域。本文将详细讲解四种解析XML文件的方法,旨在帮助初学者更好地理解和掌握XML处理技术。 ...

    基于c#的webapi断点续传几种方式及webclient断点续传下载.zip

    本资料包“基于C#的WebAPI断点续传几种方式及WebClient断点续传下载.zip”主要探讨了两种在C#环境下实现断点续传的方法:一是通过WebAPI实现服务端的断点续传功能,二是使用WebClient类进行客户端的断点续传下载。...

    易语言远程服务文件传输

    易语言远程服务文件传输是一种基于易语言编程环境实现的文件传输技术,主要用于在不同计算机之间进行数据交换。这种技术的核心在于构建一个可靠的、高效的文件传输系统,它涉及到多个关键环节,包括服务端的搭建、...

    局域网传输文件文件互传精灵

    总之,“局域网传输文件文件互传精灵”是一款旨在简化局域网内文件传输的工具,它的便捷性和高效性使得在办公室、家庭或团队协作环境中,文件共享变得更加轻松。用户只需要掌握基本的电脑操作,就能充分利用这款软件...

    java文件传输程序 源码+jar文件

    Java文件传输程序是一种基于Java编程语言开发的应用,用于在计算机之间高效、可靠地移动或复制文件。本项目源码提供了一个基本的实现,支持多线程传输,这使得它能够同时处理多个文件,提高整体传输效率。然而,由于...

    基于嵌入式Linux的无线文件传输系统的实现.pdf

    基于嵌入式Linux的无线文件传输系统可以实现文件的无线传输,提高了文件传输的速度和效率。该系统具有良好的移植性、灵活性和可扩展性,广泛应用于各种嵌入式系统中。 关键词 * 嵌入式Linux * 无线文件传输系统 * ...

    本地文件传输器

    2. **传输模式**:可能提供单个文件传输和批量文件传输两种模式,满足不同场景的需求。 3. **进度反馈**:在文件传输过程中,通过进度条实时显示当前传输进度,让用户了解传输状态。 4. **错误处理**:在遇到文件...

    Linux 上的常用文件传输方式

    本文总结了 Linux 环境下常用的几种文件传输方法,结合具体使用实例以及对这些方法优缺点的分析对比,旨在对需要在 Linux 或 Unix 环境下进行文件传输或同步的朋友提供一些帮助。 1. FTP(File Transfer Protocol)...

    android Socket文件传输

    在Android平台上,Socket文件传输是一种常见的通信方式,尤其适用于设备间的文件共享,即使涉及的是大文件,如几十兆(MB)的数据。本文将深入探讨如何使用Android的Socket进行文件传输,以及实现过程中需要注意的关键...

    文件传输,支持断点续传,Linux下的

    本文将深入探讨Linux环境下实现断点续传的几种方法。 首先,我们最常用的是`rsync`命令,它是一款强大的文件同步工具,同时也具备断点续传功能。`rsync`不仅可以用于本地文件系统,还可以跨网络进行文件同步。例如...

    UDP文件传输.rar

    在易语言中实现UDP文件传输,需要理解并掌握以下几个关键点: 1. **UDP套接字的创建**:在易语言中,使用“创建套接字”命令创建UDP套接字,用于发送和接收数据。 2. **绑定端口**:通过“绑定套接字”命令,将...

    文件传输小程序 源代码

    在文件传输过程中,可能涉及以下几个关键技术点: 1. **数据分块**:大文件通常会被分割成多个小的数据块进行传输,这样可以提高传输效率并便于错误检测和重传。 2. **校验和**:每个数据块在传输前会计算一个校验...

    文件传输软件(速度优于QQ的文件传输软件,完全绿色)

    标题中的“文件传输软件(速度优于QQ的文件传输软件,完全绿色)”指的是这款软件在文件传输速度上超越了常见的即时通讯工具QQ,并且强调其为绿色软件,意味着它无需安装,可直接运行,不含有任何广告或不必要的捆绑...

    简单的文件传输

    为了提高文件传输的可靠性,通常还需要考虑以下几点: 1. 错误检测与恢复:通过校验码(如CRC或MD5)来检查文件传输过程中是否出现错误,并提供重传机制。 2. 断点续传:如果传输中断,能够从上次断开的地方继续...

    UDP 文件传输 学习QQ文件传输

    学习UDP文件传输,首先需要理解以下几个核心概念: 1. 数据报:UDP协议基于数据报进行通信,每个数据报都是独立的,包含完整的源和目的地址,可以独立于其他数据报发送。 2. 不连接性:UDP无需建立连接即可发送...

    飞鸽传输软件(实现在局域网内大文件快速传输)

    飞鸽传输软件是一款专为局域网设计的高效文件传输工具,它允许用户在无需安装的情况下,通过执行`.EXE`可执行文件实现快速、便捷的...它简化了文件传输的过程,提升了协作效率,同时在一定程度上保证了数据的安全性。

    LINUX下传输文件源码

    这个名为“LINUX下传输文件源码”的项目提供了一种解决方案,旨在处理文件传输过程中的各种细节问题。源码是用C语言编写的,这是一门底层、高效且广泛应用的编程语言,非常适合处理系统级任务。 C语言在Linux环境下...

    p2p.rar_P2P_P2P 文件传输_P2P文件传输_易语言p2p传输

    在P2P文件传输场景中,易语言可以用来编写P2P应用程序,实现文件的上传、下载、断点续传等功能。通过易语言,开发者可以构建用户友好的界面,简化P2P协议的实现,并处理网络连接、数据传输等相关问题。 在实际的P2P...

    Socket编程实现文件传输

    - **同步与异步**:可以选择同步或异步方式进行文件传输,同步方式简单但效率较低,异步方式可提高效率但实现复杂。 - **流量控制**:考虑网络状况,适当调整发送速率,防止拥塞。 以上就是利用C/C++在Windows环境...

Global site tag (gtag.js) - Google Analytics