Java中用内存映射处理大文件
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验。
- package test;
- import java.io.BufferedInputStream;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.nio.MappedByteBuffer;
- import java.nio.channels.FileChannel;
- public class Test {
- public static void main(String[] args) {
- try {
- FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- try {
- while((n=fis.read())>=0){
- sum+=n;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- try {
- FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
- BufferedInputStream bis=new BufferedInputStream(fis);
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- try {
- while((n=bis.read())>=0){
- sum+=n;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- MappedByteBuffer buffer=null;
- try {
- buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- for(int i=0;i<1253244;i++){
- n=0x000000ff&buffer.get(i);
- sum+=n;
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
测试文件为一个大小为1253244字节的文件。测试结果:
sum:220152087 time:1464
sum:220152087 time:72
sum:220152087 time:25
说明读数据无误。删去其中的数据处理部分。
- package test;
- import java.io.BufferedInputStream;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.nio.MappedByteBuffer;
- import java.nio.channels.FileChannel;
- public class Test {
- public static void main(String[] args) {
- try {
- FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- try {
- while((n=fis.read())>=0){
- //sum+=n;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- try {
- FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
- BufferedInputStream bis=new BufferedInputStream(fis);
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- try {
- while((n=bis.read())>=0){
- //sum+=n;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- MappedByteBuffer buffer=null;
- try {
- buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- for(int i=0;i<1253244;i++){
- //n=0x000000ff&buffer.get(i);
- //sum+=n;
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
测试结果:
sum:0 time:1458
sum:0 time:67
sum:0 time:8
由此可见,将文件部分或者全部映射到内存后进行读写,速度将提高很多。
这是因为内存映射文件首先将外存上的文件映射到内存中的一块连续区域,被当成一个字节数组进行处理,读写操作直接对内存进行操作,而后再将内存区域重新映射到外存文件,这就节省了中间频繁的对外存进行读写的时间,大大降低了读写时间。
Java中用内存映射处理大文件的更多相关文章
- Java使用内存映射实现大文件的上传
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如 ...
- Delphi 中内存映射对于大文件的使用
这篇文章主要介绍了Delphi 中内存映射对于大文件的使用的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下 Delphi 中内存映射对于大文件的使用 平时很少使用大文件的内存映射,碰巧遇到了 ...
- Java NIO内存映射---上G大文件处理(转)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果 ...
- Java NIO 内存映射文件
Java NIO 内存映射文件 @author ixenos 文件操作的四大方法 前提:内存的访问速度比磁盘高几个数量级,但是基本的IO操作是直接调用native方法获得驱动和磁盘交互的,IO速度限制 ...
- Java利用内存映射文件实现按行读取文件
我们知道内存映射文件读取是各种读取方式中速度最快的,但是内存映射文件读取的API里没有提供按行读取的方法,需要自己实现.下面就是我利用内存映射文件实现按行读取文件的方法,如有错误之处请指出,或者有更好 ...
- JAVA NIO 内存映射(转载)
原文地址:http://blog.csdn.net/fcbayernmunchen/article/details/8635427 Java类库中的NIO包相对于IO 包来说有一个新功能是内存 ...
- 如何设置Java虚拟机内存以适应大程序的装载
Java虚拟机对于运行时的程序所占内存是有限制的,当我们的项目或者程序很大时,往往会照成内存溢出. 举个例子: public class SmallTest1 { public static void ...
- java 通过内存映射文件来提高IO读取文件性能
MappedByteBuffer out = new RandomAccessFile("src/demo20/test.dat", "rw"). getCha ...
- php 如何在有限的内存中读取大文件
突然遇到了一个要读取超过80M文件的需求,很悲剧的,不管是file_get_content还是file什么的,都会将读取的文件一次性加载到内存中. 正常情况下,我们可以使用fseek来读取,好处就是不 ...
随机推荐
- 图片和Base64之间的转换
public static Bitmap GetImageFromBase64String(string strBase) { try { MemoryStream stream = new Memo ...
- [水煮 ASP.NET Web API2 方法论](3-7)默认 Action 请求方式以及 NonActionAttribute
问题 在 Controller 中有一个 public 的方法,但是又不想将这个 publlic 方法暴露成为一个 API. 解决方案 ASP.NET Web API 中,正常是通过 HTTP 谓词来 ...
- Wojilu学习笔记 (02)
使用RequireJS (1)整个页面,应该只有一个 <script src="" > 标签,并且放在页面底部,用来引入 RequireJS 和 main.js 文件 ...
- SignalR入门之小试身手
建立好持久性连接类TestConnection之后,现在为我们的SignalR程序配置持久性连接类以及访问路径. 进入刚刚建立的Startup类,进入Configuration这个方法里来配置: us ...
- redis sentinel 集群配置-主从切换
1.配置redis master,redis slave(配置具体操作见上文http://www.cnblogs.com/wangchaozhi/p/5140469.html). redis mast ...
- linux 如何改变文件属性与权限
我们知道档案权限对于一个系统的安全重要性,也知道档案的权限对于使用者与群组的相关性, 那如何修改一个档案的属性与权限呢? 我们这里介绍几个常用于群组.拥有者.各种身份的权限的指令.如下所示: chgr ...
- Linux CentOS 6.6安装JDK1.7
Linux CentOS 6.6安装JDK1.7 目录 1.下载JDK 2.卸载JDK 3.安装JDK 3.1..rpm后缀格式JDK安装方式 3.2..tar.gz后缀格式JDK安装方式 4.验证安 ...
- (3)JSTL的fn方法库
fn:functions,fn之所以称之为方法库,是因为fn使用不像core,fmt标签那样遵循<prefix:tagName>的格式,而是遵循fn:methodName()的格式 < ...
- 设计模式之 面向对象的养猪厂的故事,C#演示(一)
对于设计模式, 从本质上说, 其最大的用途就是适应需求的变化. 因为有了设计模式,我们可以在设计阶段就为未来可能发生的变化留下足够的空间. 我们通过一个建造现代化养猪场的故事, 来讨论一下设计模式与需 ...
- Spring4学习笔记2-配置Bean
1.配置bean 配置形式:Xml和注解方式 Bean的配置方式:通过全类名(反射).工厂.FactoryBean 1.1 id必须唯一 2 Spring提供两种类型的IOC容器的实现 BeanFac ...