`

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

分享到:
评论

相关推荐

    Java基础 SE

    2. Dos命令:了解基本的命令行操作,如cd、dir、copy等,这些操作在Java开发过程中对于文件和目录的管理是必不可少的。 3. Java开发环境准备:熟悉JDK(Java Development Kit)安装和配置,这是Java开发的前提条件...

    javase笔记

    常见的DOS命令如`dir`(显示目录内容)、`cd`(改变当前目录)、`copy`(复制文件)等,熟练掌握这些命令能提高你的工作效率。 Java语言概述中,我们需要了解Java的起源、特点和应用领域。Java是由Sun Microsystems...

    JAVA资料.doc

    在Windows系统中,DOS命令是早期操作系统的一部分,尽管现在被图形界面所替代,但了解基本的DOS命令如`dir`、`cd`、`copy`等仍有助于理解文件系统的操作。 进入Java的世界,Java是一种高级的、面向对象的编程语言,...

    Java基础学习第二天

    可以创建一级或多级目录)、rd(删除目录,仅限空目录)、del(删除一个或一组文件)、copy(复制文件)、xcopy(复制文件并包括子目录)、cls(清屏)、exit(退出DOS)。这些命令对于在Windows环境下进行文件管理...

    01_Java基础(Java概述、环境变量、注释、关键字、标识符、常量)_讲义.doc

    Java技术体系包括三个主要平台:Java SE(标准版)是基础,提供了核心API;Java EE(企业版)涉及高级知识和整个Java生态系统,适合开发大型项目;Java ME(微型版)支持移动设备上的程序运行。 在Java开发环境中,...

    Java课堂笔记学习Java课堂笔记学习

    - Java SE:面向桌面应用开发。 - Java EE:面向企业级应用开发。 - Android SDK:用于 Android 应用开发。 - **Java 的开发环境**: - JDK(Java Development Kit):Java 开发工具包,包含编译器、调试器等...

    CoreJava资料整理

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

    txt文件分割源代码

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

    满汉楼管理系统,简单的mysql练手项目,设计Java SE、Druid、MySQL、JDBC.zip

    项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全栈开发),有任何使用问题欢迎随时与我联系,我会及时为您解惑,...

    Java基础资料

    - Java SE(Standard Edition):标准版,面向桌面应用程序。 - Java ME(Micro Edition):主要用于移动设备和嵌入式系统,现在通常指的是Android。 - Java EE(Enterprise Edition):企业版,主要用于Web应用...

    j2me copy功能

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

    java记事本

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

    java基础学习路线知识总结

    - **Java SE(标准版)**:适用于桌面应用程序开发的标准版本。 - **Java EE(企业版)**:为服务器端应用开发提供的高级功能集合,包括EJB、JSP、Servlet等。 - **Java ME(微型版)**:适用于嵌入式设备和消费电子...

    mysql-connector-java-6.0.6源码

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

    java学习笔记JDK6课件之十九

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

    JAVA入门资源

    1. **Java SE**:标准版,适用于桌面应用程序。 2. **Java EE**:企业版,针对大型分布式网络应用程序。 3. **Java ME**:微型版,适用于嵌入式设备和移动设备。 #### 六、Java机制 1. **垃圾回收机制**:自动管理...

    JAVA学习笔记-java学习笔记WORD样式.docx

    - **Java SE**:标准版,用于桌面应用程序开发。 - **Java ME**:微小版,适用于嵌入式设备和移动应用(如Android)。 - **Java EE**:企业版,用于Web应用程序和服务。 #### 六、JDK、JRE、JVM的关系 1. **JVM**...

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

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

Global site tag (gtag.js) - Google Analytics