在处理大文件时,如果利用普通的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. jquery输入数字随机抽奖特效

    简介:jQuery自定义数值抽奖活动代码是一款点击开始按钮计算机会产生玩家输入范围内的随机数,点击停止按钮,将显示数字最终结果的效果. 效果展示 http://hovertree.com/texiao ...

  2. iOS高效开发之Xcode应用插件

    前言:本文非原创 文章摘自 www.cocoachina.com/industry/20130918/7022.html    古人云“工欲善其事必先利其器”,打造一个强大的开发环境,是立即提升自身战 ...

  3. android listview 异步加载图片并防止错位

    网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...

  4. [python拾遗]文件操作

    文件操作 1.open()函数 open()函数主要用于文件处理,一般分为下面3个过程: 1.打开文件 2.操作文件 3.关闭文件 常见的格式示例: f = open('note.txt','r') ...

  5. Monkey测试3——Monkey测试结果分析

    Monkey测试结果分析 一. 初步分析方法: Monkey测试出现错误后,一般的差错步骤为以下几步: 1. 找到是monkey里面的哪个地方出错 2. 查看Monkey里面出错前的一些事件动作,并手 ...

  6. Webform(Linq高级查、分页、组合查询)

    一.linq高级查 1.模糊查(包含) 1 public List<User> Select(string name) 2 { 3 return con.User.Where(r => ...

  7. Strip JS – 低侵入,响应式的 Lightbox 效果

    Strip  是一个灯箱效果插件,显示的时候只会覆盖部分的页面,这使得侵扰程度较低,并留出了空间与页面上的大屏幕,同时给予小型移动设备上的经典灯箱体验.Strp JS 基于 jQuery 库实现,支持 ...

  8. jQuery.clean()方法源码分析(一)

    在jQuery 1.7.1中调用jQuery.clean()方法的地方有三处,第一次就是在我之前的随笔分析jQuery.buildFramgment()方法里面的,其实还是构造函数的一部分,在处理诸如 ...

  9. C#各种数组直接的数据复制/转换

    之前做Opengl程序,用的的C#的SharpGL这个库,里面有各种奇怪绑定的函数,比如原型为: void glInterleavedArrays(uint format, int stride, v ...

  10. sap去除后缀0方法

    原贴地址:http://fuhesap.com/SAP/179.html SHIFT str LEFT DELETING LEADING '0'.如果要在layout显示不出前面的0 格式: & ...