复制代码
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
//
普通IO
@Test
public void publicIo() throws FileNotFoundException {
try (InputStream inputStream = new FileInputStream("D:\\zeroCopyTest\\zeroCopyFile.zip");
OutputStream outputStream = new FileOutputStream("D:\\zeroCopyTest\\zeroCopyOutstream.zip");){
byte[] bytes = new byte[1024];
int len;
long start = System.currentTimeMillis();
while ((len = inputStream.read(bytes)) != -1){
outputStream.write(bytes,0,len);
}
long end = System.currentTimeMillis();
System.out.println("耗费时间: " + (end - start));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
//
普通io-buffered
@Test
public void bufferIo() throws FileNotFoundException {
try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("D:\\zeroCopyTest\\zeroCopyFile.zip")) ;
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("D:\\zeroCopyTest\\zeroCopyOutstream.zip"));){
byte[] bytes = new byte[1024];
int len;
long start = System.currentTimeMillis();
while ((len = inputStream.read(bytes)) != -1){
outputStream.write(bytes,0,len);
}
long end = System.currentTimeMillis();
System.out.println("耗费时间: " + (end - start));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
// 零拷贝-mmap
@Test
public void mmapCopyFile(){
long start = System.currentTimeMillis();
try(
FileChannel inputChannel = new FileInputStream("D:\\zeroCopyTest\\zeroCopyFile.zip").getChannel();
FileChannel outputChannel = new RandomAccessFile("D:\\zeroCopyTest\\zeroCopyOutstream.zip","rw").getChannel();
){
long size = inputChannel.size();
MappedByteBuffer mapInBuffer = inputChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
MappedByteBuffer mapOutBuffer = outputChannel.map(FileChannel.MapMode.READ_WRITE, 0, size);
byte[] buffer = new byte[1024]; // 设置数组大小为1024
int len;
while ((len = inputChannel.read(ByteBuffer.wrap(buffer))) != -1) {
byte b = mapInBuffer.get(len);
mapOutBuffer.put(b);
}
long end = System.currentTimeMillis();
System.out.println("耗费时间: " + (end - start));
}catch (Exception e){
throw new RuntimeException(e);
}
}
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
// 零拷贝-sendfile()
@Test
public void sendfileCopyFile(){
long start = System.currentTimeMillis();
try(
FileChannel inputChannel = new FileInputStream("D:\\zeroCopyTest\\zeroCopyFile.zip").getChannel();
FileChannel outputChannel = new FileOutputStream("D:\\zeroCopyTest\\zeroCopyOutstream.zip").getChannel();
){
// 方式1: 针对小于2GB文件
// 实际拷贝的大小(只会拷贝2GB, inputChannel.size() = 3GB, 那realSize也就 = 2GB)
// 参数1: 从哪里开始拷贝, 参数2: 拷贝多少个字节, 参数3: 拷贝到哪里去
// long realSize = inputChannel.transferTo(0, inputChannel.size(), outputChannel);
// 方式2: 针对大于2GB文件, 分多次读写
// 获取文件总大小
long size = inputChannel.size();
for(long left = size; left > 0;){
// 返回真实拷贝的大小
// 这里position起始拷贝位置,改为size-left(即总大小 - 剩余大小的位置), 参数2: left就是拷贝多少大小
long transferSize = inputChannel.transferTo(size - left, left, outputChannel);
// 计算出还剩余的大小
left -= transferSize;
}
long end = System.currentTimeMillis();
System.out.println("耗费时间: " + (end - start));
}catch (Exception e){
throw new RuntimeException(e);
}
}