在处理大文件时,如果利用普通的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. 一文读懂UGC:互联网上的生态秘密

    转载自近乎: UGC(User- Generated Content)用户原创生产内容,它是相对于PGC(Professionally-produced Content)专业生产内容的一种内容来源,简 ...

  2. 微软Dynamics 使用葡萄城的Wijmo 5提供移动端用户界面选择

    近日,全球最大的控件提供商葡萄城公司宣布: 葡萄城近日与微软公司达成合作,将Wijmo 产品线的HTML5和JaveScript 控件融合到微软Dynamics CRMOnline 2016版中. 随 ...

  3. jquery练习

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 【Java每日一题】20161130

    20161129问题解析请点击今日问题下方的"[Java每日一题]20161130"查看 package Nov2016; public class Ques1130 { publ ...

  5. hibernate简单注释(一.1)

    **************************************************************************************************** ...

  6. Xcode push带有cocoapods类库的项目到git仓库

    关于git之一点不熟悉,以前公司的项目搭建,版本控制这块,都是有专门的人在做,当然那时候也是用的git项目中也包含了cocoapods类库,当前公司比较闲, 所以研究了下git,用的是git.osch ...

  7. 用Apache 里面的ab做一个简单的压力测试

    我用的是xampp环境包. D:\xampp\apache\bin 进入这路径, 找到ab.exe  尝试双击打开ab.exe 但不能如愿, 这两个都是一个压力的测试软件, 是apache自带的; 好 ...

  8. 从源码角度理清memcache缓存服务

    memcache作为缓存服务器,用来提高性能,大部分互联网公司都在使用.   前言    文章的阅读的对象是中高级开发人员.系统架构师. 本篇文章,不是侧重对memcache的基础知识的总结,比如se ...

  9. 把复杂json解析成javabean

    工具:fastjson1.2.9 用其他工具也行,比如json-lib.gson 用法都差不多 先来一段json { "page": { "pagenow": ...

  10. var和dynamic的区别及如何正确使用dynamic ?

    C#中的很多关键词用法比较容易混淆,var和dynamic就是其中一组,他们都可以申明动态类型的变量,但是本质上他们还是有不少区别的.var 在编译阶段已经确定类型,在初始化时候,必须提供初始化的值, ...