在处理大文件时,如果利用普通的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. 安装部署Windows服务脚本

    @echo off Installutil.exe 程序目录 F:\test\TestWindows.exe 服务程序目录 @sc start "服务名称" @sc config ...

  2. ASP.NET MVC系列:开始

    创建Asp.Net MVC项目 从visual studio主界面开始菜单中点击“新建项目”

  3. 15天玩转redis —— 第五篇 集合对象类型

    这篇我们来看看Redis五大类型中的第四大类型:“集合类型”,集合类型还是蛮有意思的,第一个是因为它算是只使用key的Dictionary简易版, 这样说来的话,它就比Dictionary节省很多内存 ...

  4. 【Java每日一题】20161125

    package Nov2016; import java.util.LinkedList; import java.util.List; public class Ques1125 { public ...

  5. 【Java每日一题】20161116

    package Nov2016; public class Ques1116 { public static void main(String[] args){ System.out.println( ...

  6. border-style 属性

    border-style 属性用于设置元素所有边框的样式,或者单独地为各边设置边框样式. 只有当这个值不是 none 时边框才可能出现. 例子 1 border-style:dotted solid ...

  7. mysql中,ENCODE警告---Warning Code : 1287

    mysql中,ENCODE警告 共 1 行受到影响, 1 个警告 执行耗时 : 0.072 sec传送时间 : 0.001 sec总耗时 : 0.073 sec Warning Code : 1287 ...

  8. 项目总结笔记系列 Maven Session2

    主题:Maven插件 1.三个生命周期. 2.猛然间,一回首,竟然发现.之前的maven插件报错的原因,不是download的问题.是没有连接上网.在HP公司连接外网,用eclipse,是需要配置代理 ...

  9. Server Tomcat v7.0 Server at localhost was unable to&nbs 报错问题解决

    在eclipse启动tomcat时遇到超时45秒的问题: Server Tomcat v7.0 Server at localhost was unable to start within 45 se ...

  10. windows / linux系统中,端口被占用解决方法

    一.在windows操作系统中,查询端口占用和清除端口占用的程序 提升权限后用:netstat -b或用 1.查询端口占用的进程ID 点击"开始"-->"运行&qu ...