在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验。

  1. package test;
  2. import java.io.BufferedInputStream;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.IOException;
  6. import java.io.RandomAccessFile;
  7. import java.nio.MappedByteBuffer;
  8. import java.nio.channels.FileChannel;
  9. public class Test {
  10. public static void main(String[] args) {
  11. try {
  12. FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
  13. int sum=0;
  14. int n;
  15. long t1=System.currentTimeMillis();
  16. try {
  17. while((n=fis.read())>=0){
  18. sum+=n;
  19. }
  20. } catch (IOException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. }
  24. long t=System.currentTimeMillis()-t1;
  25. System.out.println("sum:"+sum+"  time:"+t);
  26. } catch (FileNotFoundException e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. }
  30. try {
  31. FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
  32. BufferedInputStream bis=new BufferedInputStream(fis);
  33. int sum=0;
  34. int n;
  35. long t1=System.currentTimeMillis();
  36. try {
  37. while((n=bis.read())>=0){
  38. sum+=n;
  39. }
  40. } catch (IOException e) {
  41. // TODO Auto-generated catch block
  42. e.printStackTrace();
  43. }
  44. long t=System.currentTimeMillis()-t1;
  45. System.out.println("sum:"+sum+"  time:"+t);
  46. } catch (FileNotFoundException e) {
  47. // TODO Auto-generated catch block
  48. e.printStackTrace();
  49. }
  50. MappedByteBuffer buffer=null;
  51. try {
  52. buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
  53. int sum=0;
  54. int n;
  55. long t1=System.currentTimeMillis();
  56. for(int i=0;i<1253244;i++){
  57. n=0x000000ff&buffer.get(i);
  58. sum+=n;
  59. }
  60. long t=System.currentTimeMillis()-t1;
  61. System.out.println("sum:"+sum+"  time:"+t);
  62. } catch (FileNotFoundException e) {
  63. // TODO Auto-generated catch block
  64. e.printStackTrace();
  65. } catch (IOException e) {
  66. // TODO Auto-generated catch block
  67. e.printStackTrace();
  68. }
  69. }
  70. }

测试文件为一个大小为1253244字节的文件。测试结果:

sum:220152087  time:1464
sum:220152087  time:72
sum:220152087  time:25

说明读数据无误。删去其中的数据处理部分。

  1. package test;
  2. import java.io.BufferedInputStream;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.IOException;
  6. import java.io.RandomAccessFile;
  7. import java.nio.MappedByteBuffer;
  8. import java.nio.channels.FileChannel;
  9. public class Test {
  10. public static void main(String[] args) {
  11. try {
  12. FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
  13. int sum=0;
  14. int n;
  15. long t1=System.currentTimeMillis();
  16. try {
  17. while((n=fis.read())>=0){
  18. //sum+=n;
  19. }
  20. } catch (IOException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. }
  24. long t=System.currentTimeMillis()-t1;
  25. System.out.println("sum:"+sum+"  time:"+t);
  26. } catch (FileNotFoundException e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. }
  30. try {
  31. FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
  32. BufferedInputStream bis=new BufferedInputStream(fis);
  33. int sum=0;
  34. int n;
  35. long t1=System.currentTimeMillis();
  36. try {
  37. while((n=bis.read())>=0){
  38. //sum+=n;
  39. }
  40. } catch (IOException e) {
  41. // TODO Auto-generated catch block
  42. e.printStackTrace();
  43. }
  44. long t=System.currentTimeMillis()-t1;
  45. System.out.println("sum:"+sum+"  time:"+t);
  46. } catch (FileNotFoundException e) {
  47. // TODO Auto-generated catch block
  48. e.printStackTrace();
  49. }
  50. MappedByteBuffer buffer=null;
  51. try {
  52. buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
  53. int sum=0;
  54. int n;
  55. long t1=System.currentTimeMillis();
  56. for(int i=0;i<1253244;i++){
  57. //n=0x000000ff&buffer.get(i);
  58. //sum+=n;
  59. }
  60. long t=System.currentTimeMillis()-t1;
  61. System.out.println("sum:"+sum+"  time:"+t);
  62. } catch (FileNotFoundException e) {
  63. // TODO Auto-generated catch block
  64. e.printStackTrace();
  65. } catch (IOException e) {
  66. // TODO Auto-generated catch block
  67. e.printStackTrace();
  68. }
  69. }
  70. }

测试结果:

sum:0  time:1458
sum:0  time:67
sum:0  time:8

由此可见,将文件部分或者全部映射到内存后进行读写,速度将提高很多。

这是因为内存映射文件首先将外存上的文件映射到内存中的一块连续区域,被当成一个字节数组进行处理,读写操作直接对内存进行操作,而后再将内存区域重新映射到外存文件,这就节省了中间频繁的对外存进行读写的时间,大大降低了读写时间。

Java中用内存映射处理大文件的更多相关文章

  1. Java使用内存映射实现大文件的上传

    在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如 ...

  2. Delphi 中内存映射对于大文件的使用

    这篇文章主要介绍了Delphi 中内存映射对于大文件的使用的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下 Delphi 中内存映射对于大文件的使用 平时很少使用大文件的内存映射,碰巧遇到了 ...

  3. Java NIO内存映射---上G大文件处理(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果 ...

  4. Java NIO 内存映射文件

    Java NIO 内存映射文件 @author ixenos 文件操作的四大方法 前提:内存的访问速度比磁盘高几个数量级,但是基本的IO操作是直接调用native方法获得驱动和磁盘交互的,IO速度限制 ...

  5. Java利用内存映射文件实现按行读取文件

    我们知道内存映射文件读取是各种读取方式中速度最快的,但是内存映射文件读取的API里没有提供按行读取的方法,需要自己实现.下面就是我利用内存映射文件实现按行读取文件的方法,如有错误之处请指出,或者有更好 ...

  6. JAVA NIO 内存映射(转载)

    原文地址:http://blog.csdn.net/fcbayernmunchen/article/details/8635427     Java类库中的NIO包相对于IO 包来说有一个新功能是内存 ...

  7. 如何设置Java虚拟机内存以适应大程序的装载

    Java虚拟机对于运行时的程序所占内存是有限制的,当我们的项目或者程序很大时,往往会照成内存溢出. 举个例子: public class SmallTest1 { public static void ...

  8. java 通过内存映射文件来提高IO读取文件性能

    MappedByteBuffer out = new RandomAccessFile("src/demo20/test.dat", "rw"). getCha ...

  9. php 如何在有限的内存中读取大文件

    突然遇到了一个要读取超过80M文件的需求,很悲剧的,不管是file_get_content还是file什么的,都会将读取的文件一次性加载到内存中. 正常情况下,我们可以使用fseek来读取,好处就是不 ...

随机推荐

  1. TreeView 自定义显示checkbox

    本项目需要对TreeView进行定制,要求比较简单,主要要求如下: Winform中TreeView控件默认只支持所有级别的CheckBox显示或者不显示,不能控制制定Level的树节点显示 效果如下 ...

  2. MySQL 5.1 参考手册CHM (官方 简体中文版)

    点此下载: MySQL 5.1 参考手册CHM (官方 简体中文版) 在线文档:http://doc.mysql.cn/mysql5/refman-5.1-zh.html-chapter/

  3. Java总结篇系列:Java String

    String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. 1 ...

  4. ROW_NUMBER、RANK()、DENSE_RANK()和OVER的使用

    /*以FoodPrice列排序并显示排序后的行号*/ SELECT ROW_NUMBER() OVER(ORDER BY FoodPrice DESC) AS RowId,* FROM dbo.Foo ...

  5. python mysql Connect Pool mysql连接池 (201

     easy_install mysql-connector-python >>>import mysql.connector as conner >>> conn ...

  6. genymotion和eclipse连接问题,一直出错

    前两天重装系统,但是在运行android代码的时候遇到了这样的问题 The connection to adb is down,and a server error has occured. You ...

  7. 理解Ruby中的作用域

    作用域对于Ruby以及其它编程语言都是一个需要理解的至关重要的基础知识.在我刚开始学习ruby的时候遇到很多诸如变量未定义.变量没有正确赋值之类的问题,归根结底是因为自己对于ruby作用域的了解不够, ...

  8. SDL教程第一和第二个视频的笔记

    观看正月点灯笼的SDL教程,地址http://www.tudou.com/listplay/9eG9tkk91oQ.html #include <stdio.h> #include < ...

  9. CI框架源码阅读笔记8 控制器Controller.php

    最近时间有些紧,源码阅读系列更新有些慢.鉴于Controller中代码比较少,本次Blog先更新该文件的源码分析. 在经过路由分发之后,实际的应用Controller接管用户的所有请求,并负责与用户数 ...

  10. Alfresco 4 项目介绍

    body{ font: 16px/1.5em 微软雅黑,arial,verdana,helvetica,sans-serif; }       Alfresco 是一个开源的企业内容管理系统(ECM) ...