cari
RumahJavajavaTutorialjava中io与nio复制文件性能对比

1.  在JAVA传统的IO系统中,读取磁盘文件数据的过程如下:

以FileInputStream类为例,该类有一个read(byte b[])方法,byte b[]是我们要存储读取到用户空间的缓冲区。参看read(byte b[])方法的源码,可知,它会在内部再调用readBytes(b, 0, b.length)方法,而且readBytes(b, 0, b.length)方法是一个native方法(即本地方法),最终通过这个本地方法来发起一次系统调用,即调用系统内核的read()方法,内核从磁盘读取数据到内核缓冲区,这个过程由磁盘控制器通过DMA操作将数据从磁盘读取内核缓冲区,此过程不依赖于CPU。然后用户进程再将数据从内核缓冲区拷贝到用户空间缓冲区。用户进程再从用户空间缓冲区中读取数据。因为用户进程是不可以直接访问硬件的。所以需要通过内核来充当中间人的作用来实现文件的读取。

整个过程如下图所示:55651933a6254.jpg

2.  自从JAVA 1.4以后,JAVA在NIO在引入了文件通道的概念,和传统IO最大的区别是:传统IO是基于Byte(字节)和Stream(流)的,而NIO是基于Buffer(缓冲)、Channel(通道)在API中有提供了一个FileChannel类和Selector(选择器)的,该类与传统的IO流进行关联。可以由FileInputStream或FileOutputStream获取该文件通道,我们可以通过通道对文件进行读写操作。

3.JAVA NIO中还引入了文件内存映射的概念:现代操作系统大都支持虚拟内存映射,这样,我们可以把内核空间地址与用户空间的虚拟地址映射到同一个物理地址,这样,DMA 硬件(只能访问物理内存地址)就可以填充对内核与用户空间进程同时可见的缓冲区了。如下图所示:

55651933a6254.jpg

下面就看下使用IO,BufferedIO和NIO分别实现的文件复制耗时比较:11兆音频文件

传统IO方法实现文件拷贝耗时:21ms
利用NIO文件通道方法实现文件拷贝耗时:16ms
利用NIO文件内存映射及文件通道实现文件拷贝耗时:7ms
利用FileUtils文件拷贝工具类耗时:53ms

package com.maystar.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

import org.apache.commons.io.FileUtils;

public class FileCopyTest { 
     
      public  static  void main(String[] args) throws Exception { 
     
         String sourcePath = "F:\\glzmv.mp3"; 
     
         String destPath1 = "F:\\glzmvCopy1.mp3"; 
     
         String destPath2 = "F:\\glzmvCopy2.mp3"; 
     
         String destPath3 = "F:\\glzmvCopy3.mp3"; 
         
         String destPath4 = "F:\\glzmvCopy4.mp3"; 
         long t1 = System.currentTimeMillis(); 
    
         traditionalCopy(sourcePath,destPath1); 
     
         long t2 = System.currentTimeMillis(); 
     
         System.out.println("传统IO方法实现文件拷贝耗时:" + (t2-t1) + "ms"); 
     
         nioCopy(sourcePath,destPath2); 
     
         long t3 = System.currentTimeMillis(); 
     
         System.out.println("利用NIO文件通道方法实现文件拷贝耗时:" + (t3-t2) + "ms"); 
         nioCopy2(sourcePath,destPath3); 
     
         long t4 = System.currentTimeMillis(); 
     
         System.out.println("利用NIO文件内存映射及文件通道实现文件拷贝耗时:" + (t4-t3) + "ms"); 
         
         nioCopy3(sourcePath,destPath4); 
         long t5 = System.currentTimeMillis(); 
         System.out.println("利用FileUtils文件拷贝耗时:" + (t5-t4) + "ms"); 
      } 
      private  static  void nioCopy3(String sourcePath, String destPath) throws Exception { 
             
          File source = new File(sourcePath); 
      
          File dest = new File(destPath); 
      
      
         FileUtils.copyFile(source, dest);//查看源码commons-io-2.4也使用的是nio操作,实现类似nioCopy操作,但是为什么效率比nioCopy要低,原因是在FileUtils.copyFile执行doCopyFile完成调用IOUtils工具类关闭流操作,根据不同类型的流调用对应的构造方法。
      
       } 
      
      private  static  void nioCopy2(String sourcePath, String destPath) throws Exception { 
     
         File source = new File(sourcePath); 
     
         File dest = new File(destPath); 
     
         if(!dest.exists()) { 
     
             dest.createNewFile(); 
         } 
         FileInputStream fis = new FileInputStream(source); 
     
         FileOutputStream fos = new FileOutputStream(dest); 
     
         FileChannel sourceCh = fis.getChannel(); 
     
         FileChannel destCh = fos.getChannel(); 
     
         MappedByteBuffer mbb = sourceCh.map(FileChannel.MapMode.READ_ONLY, 0, sourceCh.size()); 
     
         destCh.write(mbb); 
     
         sourceCh.close(); 
     
         destCh.close(); 
     
      } 
     
      private  static  void traditionalCopy(String sourcePath, String destPath) throws Exception{ 
     
         File source = new File(sourcePath); 
     
         File dest = new File(destPath); 
     
         if(!dest.exists()) { 
    
            dest.createNewFile(); 
    
        } 
    
        FileInputStream fis = new FileInputStream(source); 
    
        FileOutputStream fos = new FileOutputStream(dest); 
    
        byte [] buf = new byte [fis.available()]; 
    
        int len = 0; 
    
        while((len = fis.read(buf)) != -1) { 
    
            fos.write(buf, 0, len); 
    
        } 
    
        fis.close(); 
    
        fos.close(); 
    
     } 
    
     private  static  void nioCopy(String sourcePath, String destPath) throws Exception{ 
    
        File source = new File(sourcePath); 
    
        File dest = new File(destPath); 
    
        if(!dest.exists()) { 
    
            dest.createNewFile(); 
    
        } 
    
        FileInputStream fis = new FileInputStream(source); 
    
        FileOutputStream fos = new FileOutputStream(dest); 
    
        FileChannel sourceCh = fis.getChannel(); 
       
    
        FileChannel destCh = fos.getChannel(); 
        destCh.transferFrom(sourceCh, 0, sourceCh.size()); 
    
        sourceCh.close(); 
    
        destCh.close(); 
    
     } 
    
 } 


Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan?Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan?Mar 17, 2025 pm 05:46 PM

Artikel ini membincangkan menggunakan Maven dan Gradle untuk Pengurusan Projek Java, membina automasi, dan resolusi pergantungan, membandingkan pendekatan dan strategi pengoptimuman mereka.

Bagaimanakah saya membuat dan menggunakan perpustakaan Java Custom (fail JAR) dengan pengurusan versi dan pergantungan yang betul?Bagaimanakah saya membuat dan menggunakan perpustakaan Java Custom (fail JAR) dengan pengurusan versi dan pergantungan yang betul?Mar 17, 2025 pm 05:45 PM

Artikel ini membincangkan membuat dan menggunakan perpustakaan Java tersuai (fail balang) dengan pengurusan versi dan pergantungan yang betul, menggunakan alat seperti Maven dan Gradle.

Bagaimanakah saya melaksanakan caching pelbagai peringkat dalam aplikasi java menggunakan perpustakaan seperti kafein atau cache jambu?Bagaimanakah saya melaksanakan caching pelbagai peringkat dalam aplikasi java menggunakan perpustakaan seperti kafein atau cache jambu?Mar 17, 2025 pm 05:44 PM

Artikel ini membincangkan pelaksanaan caching pelbagai peringkat di Java menggunakan kafein dan cache jambu untuk meningkatkan prestasi aplikasi. Ia meliputi persediaan, integrasi, dan faedah prestasi, bersama -sama dengan Pengurusan Dasar Konfigurasi dan Pengusiran PRA Terbaik

Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas?Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas?Mar 17, 2025 pm 05:43 PM

Artikel ini membincangkan menggunakan JPA untuk pemetaan objek-relasi dengan ciri-ciri canggih seperti caching dan pemuatan malas. Ia meliputi persediaan, pemetaan entiti, dan amalan terbaik untuk mengoptimumkan prestasi sambil menonjolkan potensi perangkap. [159 aksara]

Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka?Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka?Mar 17, 2025 pm 05:35 PM

Kelas kelas Java melibatkan pemuatan, menghubungkan, dan memulakan kelas menggunakan sistem hierarki dengan bootstrap, lanjutan, dan pemuat kelas aplikasi. Model delegasi induk memastikan kelas teras dimuatkan dahulu, yang mempengaruhi LOA kelas tersuai

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Arahan sembang dan cara menggunakannya
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

mPDF

mPDF

mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

Pelayar Peperiksaan Selamat

Pelayar Peperiksaan Selamat

Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual