java_croe 學習筆記之新IO—java.nio 之記憶體對應檔

來源:互聯網
上載者:User

發布日期: 2009-8-25 23:37:54 作者:  摘自來源: JavaEye部落格 

http://12616383.javaeye.com/blog/457582

 

參考:

無格式輸入資料流 110秒

緩衝輸入資料流     9.9秒

隨機存取檔案  162秒

記憶體對應檔   7.2秒

 

例子

Java代碼
  1. package twelve;   
  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.InputStream;   
  8. import java.io.RandomAccessFile;   
  9. import java.nio.MappedByteBuffer;   
  10. import java.nio.channels.FileChannel;   
  11. import java.util.zip.CRC32;   
  12.   
  13. /**  
  14.   @Title NIOTTest.java  
  15.   @description  TODO  
  16.   @author qinpeng  
  17.   @date Aug 25, 2009 10:23:26 PM  
  18.  */  
  19. public class NIOTTest {   
  20.        
  21.     public static void main(String[] args) {   
  22.            
  23.         String fileName = "d://IOTest.pdf";   
  24.            
  25.         System.out.println("inputStream");   
  26.         long start = System.currentTimeMillis();   
  27.         long crcValue = checksumInputStreanm(fileName);   
  28.         long end = System.currentTimeMillis();   
  29.         System.out.println(Long.toHexString(crcValue));   
  30.         System.out.println((end - start)+"耗時");   
  31.            
  32.         System.out.println("BufferedinputStream");   
  33.         start = System.currentTimeMillis();   
  34.         crcValue = checksumInputStreanm(fileName);   
  35.         end = System.currentTimeMillis();   
  36.         System.out.println(Long.toHexString(crcValue));   
  37.         System.out.println((end - start)+"耗時");   
  38.            
  39.         System.out.println("RandomAccessFileinputStream");   
  40.         start = System.currentTimeMillis();   
  41.         crcValue = checksumInputStreanm(fileName);   
  42.         end = System.currentTimeMillis();   
  43.         System.out.println(Long.toHexString(crcValue));   
  44.         System.out.println((end - start)+"耗時");   
  45.            
  46.         System.out.println(" MappedFile inputStream");   
  47.         start = System.currentTimeMillis();   
  48.         crcValue = checksumInputStreanm(fileName);   
  49.         end = System.currentTimeMillis();   
  50.         System.out.println(Long.toHexString(crcValue));   
  51.         System.out.println((end - start)+"耗時");   
  52.     }   
  53.        
  54.        
  55.        
  56.     public static long checksumInputStreanm(String fileName){   
  57.         CRC32 crc = new CRC32();   
  58.         try {   
  59.             InputStream in = new FileInputStream(fileName);   
  60.             int c;   
  61.             while((c=in.read())!=-1){   
  62.                 crc.update(c);   
  63.             }   
  64.         } catch (FileNotFoundException e) {   
  65.             e.printStackTrace();   
  66.             System.err.print("NIOTTest--checksumInputStreanm--new FileInputStream is not found");   
  67.         } catch(IOException ioe){   
  68.             ioe.printStackTrace();   
  69.             System.err.print("NIOTTest--checksumInputStreanm--new FileInputStream'read append IOException");   
  70.         }   
  71.         return crc.getValue();   
  72.     }   
  73.        
  74.     public static long checksumBufferedInputStream(String fileName){   
  75.         CRC32 crc = new CRC32();   
  76.         try {   
  77.             InputStream in = new BufferedInputStream(new FileInputStream(fileName));   
  78.             int c;   
  79.             while((c=in.read())!=-1){   
  80.                 crc.update(c);   
  81.             }   
  82.         } catch (FileNotFoundException e) {   
  83.             e.printStackTrace();   
  84.             System.err.print("NIOTTest--checksumBufferedInputStream--new FileInputStream is not found");   
  85.         } catch(IOException ioe){   
  86.             ioe.printStackTrace();   
  87.             System.err.print("NIOTTest--checksumBufferedInputStream--new FileInputStream'read append IOException");   
  88.         }   
  89.         return crc.getValue();   
  90.     }   
  91.        
  92.        
  93.     public static long checksumRondomAccessFileInputStream(String fileName){   
  94.         CRC32 crc = new CRC32();   
  95.         try {   
  96.             RandomAccessFile file = new RandomAccessFile(fileName,"r");   
  97.             int c;   
  98.             while((c=file.read())!=-1){   
  99.                 crc.update(c);   
  100.             }   
  101.         } catch (FileNotFoundException e) {   
  102.             e.printStackTrace();   
  103.             System.err.print("NIOTTest--checksumRondomAccessFileInputStream--new FileInputStream is not found");   
  104.         } catch(IOException ioe){   
  105.             ioe.printStackTrace();   
  106.             System.err.print("NIOTTest--checksumRondomAccessFileInputStream--new FileInputStream'read append IOException");   
  107.         }   
  108.         return crc.getValue();   
  109.     }   
  110.   
  111.     public static long checksumMappedFile(String fileName){   
  112.         CRC32 crc = new CRC32();   
  113.         try {   
  114.             FileInputStream in = new FileInputStream(fileName);   
  115.             FileChannel channel = in.getChannel();   
  116.             int length = (int) channel.size();   
  117.             MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, length);   
  118.                
  119.             for(int p = 0;p<length;p++){   
  120.                 int c = buffer.getInt(p);   
  121.                 crc.update(c);   
  122.             }   
  123.         } catch (FileNotFoundException e) {   
  124.             e.printStackTrace();   
  125.             System.err.print("NIOTTest--checksumRondomAccessFileInputStream--new FileInputStream is not found");   
  126.         } catch(IOException ioe){   
  127.             ioe.printStackTrace();   
  128.             System.err.print("NIOTTest--checksumRondomAccessFileInputStream--new FileInputStream'read append IOException");   
  129.         }   
  130.         return crc.getValue();   
  131.     }   
  132.        
  133.        
  134. }  

------------------------------------------------】

有了記憶體對應檔,你就可以認為檔案已經全部讀進了記憶體,然後把它當成一個非常大的數組來訪問了。這種解決思路能大大簡化修改檔案的代碼。下面就是一個簡單的例子:

代碼
import java.io.*;  
import java.nio.*;  
import java.nio.channels.*;  
public class LargeMappedFiles {  
  static int length = 0x8FFFFFF; // 128 Mb  
  public static void main(String[] args) throws Exception {  
    MappedByteBuffer out =   
      new RandomAccessFile("test.dat", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);  
    for(int i = 0; i < length; i++)  
      out.put((byte)'x');  
    System.out.println("Finished writing");  
    for(int i = length/2; i < length/2 + 6; i++)  
      System.out.print((char)out.get(i));  
  }  
}  
    為了能以讀寫的方式開啟檔案,我們從RandomAccessFile入手。

    拿到channel之後,我們用map( )方法產生了一個MappedByteBuffer。這是一種特殊的"direct buffer"。注意,你必須指明,它是從檔案的哪個位置開始映射的,映射的範圍又有多大;也就是說,它還可以映射一個大檔案的某個小片斷。

   MappedByteBuffer是ByteBuffer的衍生類別,因此它具備了ByteBuffer的所有方法。這裡只簡單地示範了一下put( )和get( )方法,除此之外,你還可以使用asCharBuffer( )之類的方法。
    上述常式建立了一個128MB的檔案,或許這已經超出OS的允許範圍了。檔案的訪問好像只是一瞬間的事,這是因為,真正調入記憶體的只是其中的一小部分,其餘部分則被放在分頁檔上。這樣你就可以很方便地修改超大型的檔案了(最大可以到2 GB)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.