FileInputStream RandomAccessFile FileChannel 与 MappedByteBuffer (yet)

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

    1. MappedByteBuffer使用虚拟内存,因此分配(map)的内存大小不受JVM的-Xmx参数限制,但是也是有大小限制的。
    2. 如果当文件超出1.5G限制时,可以通过position参数重新map文件后面的内容。
    3. 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

其它参考:

MappedByteBuffer VS FileChannel 孰强孰弱?

原文地址:https://www.cnblogs.com/silyvin/p/11579012.html