package read;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
/**
* Created by joyce on 2019/9/23.
*/
public class FormerReader {
public static void main(String [] f) throws Exception {
File fileIn = new File("/Users/joyce/Downloads/java.pdf"); //打开源文件
File fileOut = new File("/Users/joyce/Downloads/target.pdf");
// 普通stream方式
long formerStart = System.currentTimeMillis();
FileInputStream streamln = new FileInputStream (fileIn);
FileOutputStream streamOut = new FileOutputStream (fileOut);
int c;
while ((c = streamln.read()) != -1) {
streamOut.write(c);
}
streamln.close();
streamOut.close();
long formerEnd = System.currentTimeMillis();
System.out.println((formerStart-formerEnd)/1000);
// randomaccessFile
formerStart = System.currentTimeMillis();
RandomAccessFile randomAccessFileR = new RandomAccessFile(fileIn, "r");
RandomAccessFile randomAccessFileW = new RandomAccessFile(fileOut, "rw");
byte[] buf = new byte[1024];
while((randomAccessFileR.read(buf)) != -1) {
randomAccessFileW.write(buf);
}
formerEnd = System.currentTimeMillis();
System.out.println((formerStart-formerEnd)/1000);
// nio
formerStart = System.currentTimeMillis();
FileChannel fileChannelIn = new RandomAccessFile(fileIn, "r").getChannel();
FileChannel fileChannelOut = new RandomAccessFile(fileOut, "rw").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(48);
int bytesRead = fileChannelIn.read(buffer);
while(bytesRead != -1){
buffer.flip();
fileChannelOut.write(buffer);
buffer.clear();
bytesRead = fileChannelIn.read(buffer);
}
formerEnd = System.currentTimeMillis();
System.out.println((formerStart-formerEnd)/1000);
// nio MappedByteBuffer
formerStart = System.currentTimeMillis();
long len = fileIn.length();
MappedByteBuffer mappedByteBuffer = new RandomAccessFile(fileIn, "r").getChannel().map(FileChannel.MapMode.READ_ONLY, 0, len);
MappedByteBuffer mappedByteBufferout = new RandomAccessFile(fileOut, "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, len);
for (int offset = 0; offset < len; offset++) {
byte b = mappedByteBuffer.get();
mappedByteBufferout.put(b);
}
formerEnd = System.currentTimeMillis();
System.out.println((formerStart-formerEnd)/1000);
}
}
-283
-1
-6
0
文件26M
- MappedByteBuffer使用虚拟内存,因此分配(map)的内存大小不受JVM的-Xmx参数限制,但是也是有大小限制的。
- 如果当文件超出1.5G限制时,可以通过position参数重新map文件后面的内容。
- MappedByteBuffer在处理大文件时的确性能很高,但也存在一些问题,如内存占用、文件关闭不确定,被其打开的文件只有在垃圾回收的才会被关闭,而且这个时间点是不确定的。
javadoc中也提到:A mapped byte buffer and the file mapping that it represents remain valid until the buffer itself is garbage-collected.*
循环映射:
protected void head() { //512m long length = 1L << 29; //4g long _4G = 1L << 32; long cur = 0L; try { MappedByteBuffer mappedByteBuffer; Random random = new Random(); while (cur < _4G) { mappedByteBuffer = new RandomAccessFile("D:\test\bigfile.txt", "rw").getChannel() .map(FileChannel.MapMode.READ_WRITE, cur, length); IntBuffer intBuffer = mappedByteBuffer.asIntBuffer(); while (intBuffer.position() < intBuffer.capacity()) { intBuffer.put(random.nextInt()); } cur += length; } } catch (IOException e) { e.printStackTrace(); } } 原文链接:https://blog.csdn.net/bpz31456/article/details/82255985
其它参考: