`

JAVA SE COPY 文件

阅读更多
copy CSDN 上面的具体地址忘记copy 了!!
使用 java 进行文件拷贝 相信很多人都会用,,不过效率上是否最好呢?
最近看了看NIO决定试一试 java  NIO 到底有什么性能的提升.
第一种方法:古老的方式
public static long forJava(File f1,File f2) throws Exception{
  long time=new Date().getTime();
  int length=2097152;
  FileInputStream in=new FileInputStream(f1);
  FileOutputStream out=new FileOutputStream(f2);
  byte[] buffer=new byte[length];
  while(true){
   int ins=in.read(buffer);
   if(ins==-1){
    in.close();
    out.flush();
    out.close();
    return new Date().getTime()-time;
   }else
    out.write(buffer,0,ins);
  }
}
方法的2参数分别是原始文件,和拷贝的目的文件.这里不做过多介绍.
实现方法很简单,分别对2个文件构建输入输出流,并且使用一个字节数组作为我们内存的缓存器, 然后使用流从f1 中读出数据到缓存里,在将缓存数据写到f2里面去.这里的缓存是2MB的字节数组
第2种方法:使用NIO中的管道到管道传输
    public static long forTransfer(File f1,File f2) throws Exception{
        long time=new Date().getTime();
        int length=2097152;
        FileInputStream in=new FileInputStream(f1);
        FileOutputStream out=new FileOutputStream(f2);
        FileChannel inC=in.getChannel();
        FileChannel outC=out.getChannel();
        int i=0;
        while(true){
            if(inC.position()==inC.size()){
                inC.close();
                outC.close();
                return new Date().getTime()-time;
            }
            if((inC.size()-inC.position())<20971520)
                length=(int)(inC.size()-inC.position());
            else
                length=20971520;
            inC.transferTo(inC.position(),length,outC);
            inC.position(inC.position()+length);
            i++;
        }
    }
实现方法:在第一种实现方法基础上对输入输出流获得其管道,然后分批次的从f1的管道中像f2的管道中输入数据每次输入的数据最大为2MB
方法3:内存文件景象写(读文件没有使用文件景象,有兴趣的可以回去试试,,我就不试了,估计会更快)
    public static long forImage(File f1,File f2) throws Exception{
        long time=new Date().getTime();
        int length=2097152;
        FileInputStream in=new FileInputStream(f1);
        RandomAccessFile out=new RandomAccessFile(f2,"rw");
        FileChannel inC=in.getChannel();
        MappedByteBuffer outC=null;
        MappedByteBuffer inbuffer=null;
        byte[] b=new byte[length];
        while(true){
            if(inC.position()==inC.size()){
                inC.close();
                outC.force();
                out.close();
                return new Date().getTime()-time;
            }
            if((inC.size()-inC.position())<length){
                length=(int)(inC.size()-inC.position());
            }else{
                length=20971520;
            }
            b=new byte[length];
            inbuffer=inC.map(MapMode.READ_ONLY,inC.position(),length);
            inbuffer.load();
            inbuffer.get(b);
            outC=out.getChannel().map(MapMode.READ_WRITE,inC.position(),length);
            inC.position(b.length+inC.position());
            outC.put(b);
            outC.force();
        }
    }
实现方法:跟伤2个例子不一样,这里写文件流没有使用管道而是使用内存文件映射(假设文件f2在内存中).在循环中从f1的管道中读取数据到字节数组里,然后在像内存映射的f2文件中写数据.
第4种方法:管道对管道
    public static long forChannel(File f1,File f2) throws Exception{
        long time=new Date().getTime();
        int length=2097152;
        FileInputStream in=new FileInputStream(f1);
        FileOutputStream out=new FileOutputStream(f2);
        FileChannel inC=in.getChannel();
        FileChannel outC=out.getChannel();
        ByteBuffer b=null;
        while(true){
            if(inC.position()==inC.size()){
                inC.close();
                outC.close();
                return new Date().getTime()-time;
            }
            if((inC.size()-inC.position())<length){
                length=(int)(inC.size()-inC.position());
            }else
                length=2097152;
            b=ByteBuffer.allocateDirect(length);
            inC.read(b);
            b.flip();
            outC.write(b);
            outC.force(false);
        }
    }
这里实现方式与第3种实现方式很类似,不过没有使用内存影射.

下面是对49.3MB的文件进行拷贝的测试时间(毫秒)
Start Copy File...  file size:50290KB
CopyFile:b1.rmvb mode:forChannel  RunTime:3203
CopyFile:b1.rmvb mode:forImage  RunTime:3328
CopyFile:b1.rmvb mode:forJava  RunTime:2172
CopyFile:b1.rmvb mode:forTransfer RunTime:1406
End Copy File!
解释: 在测试结果中看到 古老方式,和管道向管道传输是最快的,,,,,为什么呢?
我分析是这样的,由于另外2种方法内部都使用了 字节数组作为缓存中转,在加上NIO内部有一个贴近系统的缓存区,这无意就增加了另一个缓存器,所以相对于这2个方法就要慢许多,,如果不使用 字节数组作为数据中转的话相信速度会更快的..
不过比较惊讶的是 管道向管道传输的速度还是真挺吓人,,, 
我的机器是 IDE硬盘120G 硬盘缓存2MB, 内存1GB, CPU AMD2800

分享到:
评论

相关推荐

    CoreJava资料整理

    - `cmd`启动命令行,`cd`切换目录,`dir`显示目录内容,`md`创建目录,`edit`编辑文本,`type`查看文件内容,`copy`复制文件,`rename`重命名文件,`del`删除文件,`cls`清屏,`exit`退出命令行。 - 使用`javac`...

    txt文件分割源代码

    本文将深入探讨一个具体的案例——“txt文件分割源代码”,这是一种利用Java编程语言实现的高效文本处理技术,适用于Java SE、EE和Android项目。 首先,让我们理解什么是txt文件。TXT文件是一种纯文本格式,通常...

    mysql-connector-java-6.0.6源码

    1. **JDBC驱动**:JDBC是Java中用于数据库操作的标准接口,由Java SE的一部分——Java Database Connectivity API提供。MySQL Connector/J实现了JDBC驱动的四个主要类型:Driver、Connection、Statement和ResultSet...

    j2me copy功能

    首先,我们要明白在`j2me`中进行文件操作与在标准Java SE环境中的操作有所不同。由于资源限制和设备特性,`j2me`没有提供像`java.io.File`类那样全面的文件操作API。但是,我们可以通过`javax.microedition.io....

    java记事本

    Swing是Java标准版(Java SE)的一部分,提供了丰富的组件集合,如JFrame(窗口)、JTextArea(文本区域)和JButton(按钮)等,用于构建图形用户界面(GUI)。而JavaFX则是一个更现代、功能更强大的图形库,它支持...

    java学习笔记JDK6课件之十九

    这是一份新手入门的学习资料,非常适合初学者掌握Java SE(标准版)环境下的Swing库,以及如何创建一个基本的文本编辑器应用。 ### 一、Swing入门 Swing是Java提供的一套图形用户界面(GUI)工具包,它是Java ...

    面向对象程序设计:JavaSE-任务101

    面向对象程序设计是Java SE(标准版)的核心特性之一,任务101主要涉及文件和流的操作,以及图像处理。在此任务中,我们将探讨如何利用Java进行文件管理、流的使用,以及图像的拆分与合并。 首先,我们来看文件管理...

    【Java软件开发常用词汇表】(按学习进度排序) .pdf

    2. **标准(Standard)**:在Java中,通常指的是Java SE(标准版),是Java的基础平台。 3. **企业(Enterprise)**:Java EE(企业版)用于开发企业级应用。 4. **微(Micro)**:与微服务架构相关,小型独立的服务...

    rad rail plugin

    7. "part5.htm, Use of JavaTM GSS-API for Secure Message Exchanges Without JAAS Programming.html, Secure Communications using the Java SE 6 Security API.html":这些文档可能详细阐述了如何使用Java GSS-...

    jdk1.7.0_51.zip

    JDK7是Java的一个重要版本,它的全名是Java SE (Standard Edition) 7,发布于2012年。这个版本引入了许多新特性和改进,旨在提高开发者的生产力并优化应用程序性能。 1. **动态类型语言支持**:JDK7通过JSR 292...

    Java7_Examples:Java 7的源代码示例

    Java 7,也被称为Java SE 7(Java Platform, Standard Edition 7),是Java编程语言的一个重大更新,它引入了许多新特性和改进,旨在提高开发人员的效率和代码的可维护性。在这个"Java7_Examples"压缩包中,我们可以...

    jamon:一个由 Java 实现的 monadic 解析器启发的解析器的愚蠢尝试

    火腿Java 中的 Monadic 组合器解析器框架 Javadoc 在发布二进制文件可以从下载可以从下载快照如果这样更方便的话,还有一个用于您的build.gradle : testCompile 'se.fnord:jamon:1.1.0'执照该软件是在许可下获得...

    jdk-7u80-linux-x64.tar.gz

    JDK是Oracle公司提供的Java编程语言和Java平台标准版(Java SE)的一部分,包含了编译器、调试器、文档、Java运行时环境(JRE)以及各种工具,如Javadoc和JAR。JDK 7是Java的一个重要版本,它引入了多项新特性,旨在...

    Syncro SVN Client 5 build 2009083115 绿色版(一)

    一个非常好用的svn客户端。Syncro SVN Client与Syntevo....下载地址可以到http://java.sun.com/javase/downloads/index.jsp,找"Java SE Runtime Environment (JRE)"这一栏。其它的JDK/SDK之类的是开发环境,不用下它。

    jdk-11.0.9_doc-all.rar

    JDK 11.0.9是Java Development Kit的第11个主要版本,是Java Standard Edition(Java SE)的重要组成部分。这个版本带来了许多新特性、增强功能以及对现有API的改进,旨在提高开发人员的生产力和应用程序的性能。...

    hadoop安装

    Java(TM) SE Runtime Environment (build 1.6.0_38-ea-b04) Java HotSpot(TM) Client VM (build 20.13-b02, mixed mode, sharing) 4.安装hadoop (3台都安) [root@a1 ~]# tar zxvf hadoop-0.20.2-cdh3u5.tar.gz -C ...

    JDK1.7的API文档

    JDK(Java Development Kit)是Oracle公司提供的用于开发和运行Java应用程序的工具集合,而JDK1.7,也被称为Java SE 7(Java Standard Edition 7),是Java语言发展的一个重要版本。这个版本在2011年发布,引入了...

    文本文件类扩展名.txt

    收集的一千多个文本文件扩展名: 1c 1f 1st 2 3 3pc 4 4gl 4th 5 51 6 68k 7 8 800 850 9 a a51 a75 aas abap abl abp abv ac acl acpi act act2000 ad ada adb adm ado ads ...

    C++大学教程,一本适合初学者的入门教材(part2)

    1.9 Java、Internet与万维网 1.10 其他高级语言 1.11 结构化编程 1.12 典型C++环境基础 1.13 C++与本书的一般说明 1.14 C++编程简介 1.15 简单程序:打印一行文本 1.16 简单程序:两个整数相加 1.17 内存的...

    C++大学教程,一本适合初学者的入门教材(part1)

    1.9 Java、Internet与万维网 1.10 其他高级语言 1.11 结构化编程 1.12 典型C++环境基础 1.13 C++与本书的一般说明 1.14 C++编程简介 1.15 简单程序:打印一行文本 1.16 简单程序:两个整数相加 1.17 内存的...

Global site tag (gtag.js) - Google Analytics