zoukankan      html  css  js  c++  java
  • Java中用内存映射处理大文件

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

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


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

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

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

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


        测试结果:

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

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

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

  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/sikewang/p/5564760.html
Copyright © 2011-2022 走看看