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来读取,好处就是不 ...
随机推荐
- Unrecognized attribute 'targetFramework'. Note that attribute names are case-sensitive.
调试网站时,异常出现:Unrecognized attribute 'targetFramework'. Note that attribute names are case-sensitive. S ...
- Socket开发框架之数据传输协议
我在前面一篇随笔<Socket开发框架之框架设计及分析>中,介绍了整个Socket开发框架的总体思路,对各个层次的基类进行了一些总结和抽象,已达到重用.简化代码的目的.本篇继续分析其中重要 ...
- Saas
SaaS是Software-as-a-Service(软件即服务)的简称,随着互联网技术的发展和应用软件的成熟, 在21世纪开始兴起的一种完全创新的软件应用模式.它与“on-demand softwa ...
- objective-c 宏定义UIAlertController公用方法
IOS的方法经常都有更迭,以前弹出框使用 AlertView,现在使用UIAlertController AlertView的宏定义 #define showMessage(__MESSAGE__) ...
- HDU 5510---Bazinga(指针模拟)
题目链接 http://acm.hdu.edu.cn/search.php?action=listproblem Problem Description Ladies and gentlemen, p ...
- [javaSE] 反射-Class类的使用
JAVA-Reflect 专题 ①Class类的使用 ②方法的反射 ③成员变量的反射 ④构造函数的反射 ⑤java类的加载机制 Ⅰ在面向对象的世界里,万事万物皆为对象 类是对象,类是java.lang ...
- easyui datagrid toolbar 添加搜索框
最近用到了就研究了下,效果 把列名稍加转换放入menubtton,对于单项搜索来说还是非常方便的 var fields = $('#tt').datagrid('getColumnFields') ...
- 赞!带进度条的 jQuery 文件拖放上传插件
jQuery File Uploader 是一个 jQuery 文件拖放上传插件,包括 Ajax 上传和进度条效果.作者编写这个插件的想法是要保持它非常简单,不像其他的插件,很多的标记,并提供一些 H ...
- Boba.js – 用于 Google 统计分析 JavaScript 库
Boba.js 是一个小的,易于扩展的 JavaScript 库,让谷歌分析(Google Analytics)的更灵活,更容易.它同时支持旧的 ga.js 库以及新的 analytics.js 库. ...
- 10个最好的 JavaScript 动画库和开发框架
虽然 CSS3 动画功能能够让我们以简单轻松的方式实现动画效果,但是浏览器兼容性问题让人头疼.不过不用担心,我们还有另外的武器——JavaScript,它同样可以帮助你实现各种各样的动画效果,而且借助 ...