四种拷贝方式
不同io buffer io mmap 零拷贝 sendfile 零拷贝
核心代码
java">package com. itzhongzi. io ; import java . io. * ;
import java . nio. MappedByteBuffer ;
import java . nio. channels. FileChannel ;
import java . nio. file. Files ;
import java . nio. file. Paths ;
public class IOTest { public static void main ( String [ ] args) { String type = args[ 0 ] ; String inputFilePath = args[ 1 ] ; String outputFilePath = args[ 2 ] ; if ( "io" . equalsIgnoreCase ( type) ) { inputStreamCopyFile ( inputFilePath, outputFilePath) ; } else if ( "buffer" . equalsIgnoreCase ( type) ) { bufferInputStreamCopyFile ( inputFilePath, outputFilePath) ; } else if ( "mmap" . equalsIgnoreCase ( type) ) { mmapInputStreamCopyFile ( inputFilePath, outputFilePath) ; } else if ( "sendfile" . equalsIgnoreCase ( type) ) { sendfileInputStreamCopyFile ( inputFilePath, outputFilePath) ; } } private static void inputStreamCopyFile ( String inputFilePath, String outputFilePath) { long start = System . currentTimeMillis ( ) ; try ( FileInputStream fis = new FileInputStream ( inputFilePath) ; FileOutputStream fos = new FileOutputStream ( outputFilePath) ) { byte [ ] buf = new byte [ 1024 ] ; int len; ; while ( ( len = fis. read ( buf) ) != - 1 ) { fos. write ( buf) ; } } catch ( Exception e) { e. printStackTrace ( ) ; } long end = System . currentTimeMillis ( ) ; System . out. println ( "耗时" + ( end - start) + "ms" ) ; } private static void bufferInputStreamCopyFile ( String inputFilePath, String outputFilePath) { long start = System . currentTimeMillis ( ) ; try ( BufferedInputStream bis = new BufferedInputStream ( Files . newInputStream ( Paths . get ( inputFilePath) ) ) ; BufferedOutputStream bos = new BufferedOutputStream ( Files . newOutputStream ( Paths . get ( outputFilePath) ) ) ; ) { byte [ ] buf = new byte [ 1024 ] ; int len; while ( ( len = bis. read ( buf) ) != - 1 ) { bos. write ( buf) ; } } catch ( Exception e) { e. printStackTrace ( ) ; } long end = System . currentTimeMillis ( ) ; System . out. println ( "耗时" + ( end - start) + "ms" ) ; } private static void mmapInputStreamCopyFile ( String inputFilePath, String outputFilePath) { try ( FileChannel channelIn = new FileInputStream ( inputFilePath) . getChannel ( ) ; FileChannel channelOut = new RandomAccessFile ( outputFilePath, "rw" ) . getChannel ( ) ; ) { long size = channelIn. size ( ) ; System . out. println ( "mmap size:" + size) ; MappedByteBuffer mappedInByteBuffer = channelIn. map ( FileChannel. MapMode . READ_ONLY , 0 , size) ; MappedByteBuffer mappedOutByteBuffer = channelOut. map ( FileChannel. MapMode . READ_WRITE , 0 , size) ; for ( int i = 0 ; i < size; i++ ) { mappedOutByteBuffer. put ( mappedInByteBuffer. get ( i) ) ; } } catch ( Exception e) { e. printStackTrace ( ) ; } } private static void sendfileInputStreamCopyFile ( String inputFilePath, String outputFilePath) { try ( FileChannel channelIn = new FileInputStream ( inputFilePath) . getChannel ( ) ; FileChannel channelOut = new FileOutputStream ( outputFilePath) . getChannel ( ) ) { long size = channelIn. size ( ) ; for ( long left = size; left > 0 ; ) { long transferSize = channelIn. transferTo ( size - left, left, channelOut) ; left = size - transferSize; } } catch ( Exception e) { e. printStackTrace ( ) ; } } }