RandomAcessFile、MappedByteBuffer和缓冲读/写文件

2024-04-13 17:32

本文主要是介绍RandomAcessFile、MappedByteBuffer和缓冲读/写文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

项目需要进行大文件的读写,调查测试的结果使我决定使用MappedByteBuffer及相关类进行文件的操作,效果不是一般的高。

网上参考资源很多,如下两篇非常不错:

1、花1K内存实现高效I/O的RandomAccessFile类
2、Java中Stream和Memory-mapped File的I/O性能对比
小结:
1、RandomAccessFile本身不带缓冲读写,和FileInputStream、FileOutputStream等一样,直接按字节读写时,性能不可接受;
2、使用MappedByteBuffer读写,固然性能会得到极大提升;其实只要自己处理缓冲,性能都会有非常大的提升,比如以下两种方式(见下记代码)中第一种使用了MappedByteBuffer,第二种自己进行缓冲,对于12M的文件,后者的效率甚至高于前者。
3、BufferedXXXX之类的缓冲流,如果仅使用默认的buffer size,性能不一定最优,要权衡不同情况各种因素设置大小。
/** 测试结果与Buffer size有关*/
// 1、使用MappedByteBuffer: 0.7s
String srcFile = "D://Noname1.txt";
String destFile = "D://copy.txt";
RandomAccessFile rafi = new RandomAccessFile(srcFile, "r");
RandomAccessFile rafo = new RandomAccessFile(destFile, "rw");
FileChannel fci = rafi.getChannel();
FileChannel fco = rafo.getChannel();
long size = fci.size();
MappedByteBuffer mbbi = fci.map(FileChannel.MapMode.READ_ONLY, 0, size);
MappedByteBuffer mbbo = fco.map(FileChannel.MapMode.READ_WRITE, 0, size);
long start = System.currentTimeMillis();
for (int i = 0; i < size; i++) {byte b = mbbi.get(i);mbbo.put(i, b);
}
fci.close();
fco.close();
rafi.close();
rafo.close();
System.out.println("Spend: " + (double) (System.currentTimeMillis() - start) / 1000 + "s");// 2、自己处理Buffer(RandomAccessFile): 0.13s	
String srcFile = "D://Noname1.txt";
String destFile = "D://copy.txt";
RandomAccessFile rafi = new RandomAccessFile(srcFile, "r");
RandomAccessFile rafo = new RandomAccessFile(destFile, "rw");byte[] buf = new byte[1024 * 8];long start = System.currentTimeMillis();int c = rafi.read(buf);while (c > 0) {if (c == buf.length) {rafo.write(buf);} else {rafo.write(buf, 0, c);}c = rafi.read(buf);
}
rafi.close();
rafo.close();
System.out.println("Spend: " + (double) (System.currentTimeMillis() - start) / 1000 + "s");// 3、BufferedInputStream&BufferedOutputStream: 3.02s
String srcFile = "D://Noname1.txt";
String destFile = "D://copy.txt";
FileInputStream rafi = new FileInputStream(srcFile);
FileOutputStream rafo = new FileOutputStream(destFile);BufferedInputStream bis = new BufferedInputStream(rafi, 8192);
BufferedOutputStream bos = new BufferedOutputStream(rafo, 8192);
long size = rafi.available();long start = System.currentTimeMillis();for (int i = 0; i < size; i++) {byte b = (byte) bis.read();bos.write(b);
}
rafi.close();
rafo.close();
System.out.println("Spend: " + (double) (System.currentTimeMillis() - start) / 1000 + "s");


这篇关于RandomAcessFile、MappedByteBuffer和缓冲读/写文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/900770

相关文章

工作集、granule、缓冲区、缓冲池概念及关系?

工作集、granule、缓冲区、缓冲池概念及关系? granule:为了让内存在db_chache_size和shared_pool_size之间高效的移动,oracle在9i重构SGA,使用固定大小的内存块即为granule。这个参数就是为什么当你分配给shared pool值的时候,为什么有时候比你分配的值要大一点,但是granule的整数倍。 缓冲区:内存存放数据的地方,类似于数

图形API学习工程(8):使用顶点索引缓冲

工程GIT地址:https://gitee.com/yaksue/yaksue-graphics 目标 在《图形API学习工程(5):图形管线&顶点缓冲》中,实现了渲染出一个三角形。 他有三个顶点。但是考虑图形变得复杂些的情况,就假如是一个四边形吧,那就需要分解为两个三角形来渲染了,而每个三角形需要三个顶点,也就是说,共需要6个顶点数据。 然而,如上图所示,实际上顶点是有重复的:0和3重复

【大数据Java基础-JAVA IO 4】JAVA IO流 (四) 缓冲流的使用

packageatguigu.senior.day11.java;importorg.junit.Test;import java.io.*;/*** 处理流之一:缓冲流的使用 1.缓冲流: BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter 2.作用:提供流的读取、写入的速度 提高读写

OpenGL双缓冲

1.双缓冲技术解决的问题 在计算机上的动画与实际的动画有些不同:实际的动画都是先画好了,播放的时候直接拿出来显示就行。计算机动画则是画一张,就拿出来一张,再画下一张,再拿出来。如果所需要绘制的图形很简单,那么这样也没什么问题。但一旦图形比较复杂,绘制需要的时间较长,问题就会变得突出。 让我们把计算机想象成一个画图比较快的人,假如他直接在屏幕上画图,而图形比较复杂,则有可能在他只画了某幅图的一半

双缓冲和单缓存的区别

双缓冲和单缓存的区别 编码时遇到glutInitDisplayMode(unsigned int mode) ;函数,主要作用是设置初始显示模式,其中有两个可用形参不甚理解。分别为GLUT_SINGLE,GLUT_DOUBLE。其中GLUT_SINGLE指定单缓存窗口,GLUT_DOUBLE指定双缓存窗口。 这里必须要搞明白双缓存窗口和单缓存窗口的区别。 单缓存窗口:实际上就是将所有的绘图指

Qt22双缓冲机制

Qt22双缓冲机制 知识点drawwidgetdrawwidget.hdrawwidget.cpp mainwindowmainwindow.hmainwindow.cpp main.cpp运行图 知识点 双缓冲就是在内存区申请一块缓存;然后显卡直接从这块内存读取数据.。 这样就不用鼠标边画,经过IO来读取这个环节; 鼠标驱动 — 内存缓冲区— 显卡 drawwidget d

【Redis】缓冲之Redis简介

** Redis简介 ** Redis是Remote Dictionary Server的缩写,它是由Salvator Sanfilippo编写的key-value存储结构,是一个使用ANSI编写,遵守BSD协议,支持网络、可基于内存也可以持久化的key-value的nosql数据库,并提供了多种语言的API,它允许缓冲的值(value)可以是字符串(string)、哈希(hash)、列表(

Direct9学习之--------------------------模板缓冲的应用

一.模板缓冲区: 板缓冲区(Stencil Buffer)与后台缓冲区大小相同,类似于深度缓冲区可以控制相似是否写入。 模板可以通过设置简单的参数及测试方法允许或者拒绝像素的写入。 利用模板缓冲技术可以实现阴影体 镜面反射 渐入渐出等效果。 这里只介绍阴影体和镜面的实现方式。 二.镜面反射:  镜面反射实现思路比较简单利用模板测试的方式分三次绘制即可实现: 1.

spark 大型项目实战(四十四):troubleshooting之控制shuffle reduce端缓冲大小以避免OOM

1. map端的task是不断的输出数据的,数据量可能是很大的。 但是,其实reduce端的task,并不是等到map端task将属于自己的那份数据全部写入磁盘文件之后,再去拉取的。map端写一点数据,reduce端task就会拉取一小部分数据,立即进行后面的聚合、算子函数的应用。 每次reduece能够拉取多少数据,就由buffer来决定。因为拉取过来的数据,都是先放在buffer中的。然

Vulkan教程 - 16 MVP与统一缓冲对象

我们现在能为每个顶点传输任意属性到顶点着色器了,但是用全局变量怎么样呢?我们本章要转移到3D图形上,这就需要Model-View-Projection矩阵了,也就是MVP矩阵(模型-视口-投影矩阵)。我们可以将它包括进来作为顶点数据,但是这比较浪费内存,也要求我们在它的变换改变的时候更新顶点缓冲,而变换是很可能在每一帧都改变的。         Vulkan中正确处理该问题的方法