import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
/**
*
*/
public class NioUtils {
private static Logger logger = LoggerFactory.getLogger(NioUtils.class);
/**
* 通过 FileChannel.map()拿到MappedByteBuffer
* 使用内存文件映射,速度会快很多
* @param file
* @param allocate 小于1则一次读取所有
* @throws IOException
*/
public static byte[] readByChannel(File file,int allocate) throws IOException {
long start = System.currentTimeMillis();
RandomAccessFile fis = new RandomAccessFile(file, "rw");
FileChannel channel = fis.getChannel();
long size = channel.size();
byte[] all=null;
// 构建一个只读的MappedByteBuffer
MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
// 如果文件不大,可以选择一次性读取到数组
if(allocate<1) {
all = new byte[(int)size];
mappedByteBuffer.get(all, 0, (int)size);
}
else {
// 如果文件内容很大,可以循环读取,计算应该读取多少次
byte[] bytes = new byte[allocate];
long cycle = size / allocate;
int mode = (int) (size % allocate);
//byte[] eachBytes = new byte[allocate];
for (int i = 0; i < cycle; i++) {
// 每次读取allocate个字节
mappedByteBuffer.get(bytes);
//合并
all=ArrayUtils.addAll(all,bytes);
}
if (mode > 0) {
bytes = new byte[mode];
mappedByteBuffer.get(bytes);
//合并
all=ArrayUtils.addAll(all,bytes);
}
}
// 关闭通道和文件流
channel.close();
fis.close();
long end = System.currentTimeMillis();
logger.debug(String.format("===>文件大小:%s 字节", size));
logger.debug(String.format("===>读取并打印文件耗时:%s毫秒", end - start));
//
return all;
}
}
java内存映射 鹿鸣自用
最新推荐文章于 2024-08-22 14:11:17 发布
该博客介绍了如何利用Java的NIO(New IO)框架中的内存映射文件技术,通过FileChannel和MappedByteBuffer高效地读取大文件。文章详细展示了读取过程,并强调了这种方式相比传统I/O在性能上的提升。
摘要由CSDN通过智能技术生成