日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Java IO的RandomAccessFile的使用

 Levy_X 2017-05-29
現(xiàn)有如下的一個(gè)需求,向已存在1G數(shù)據(jù)的txt文本里末尾追加一行文字,內(nèi)容如下“Lucene是一款非常優(yōu)秀的全文檢索庫”??赡艽蠖鄶?shù)朋友會(huì)覺得這個(gè)需求很easy,說實(shí)話,確實(shí)easy,然后XXX君開始實(shí)現(xiàn)了,直接使用Java中的流讀取了txt文本里原來所有的數(shù)據(jù)轉(zhuǎn)成字符串后,然后拼接了“Lucene是一款非常優(yōu)秀的全文檢索庫”,又寫回文本里了,至此,大功告成。后來需求改了,向5G數(shù)據(jù)的txt文本里追加了,結(jié)果XXX君傻了,他內(nèi)存只有4G,如果強(qiáng)制讀取所有的數(shù)據(jù)并追加,會(huì)報(bào)內(nèi)存溢出的異常。

其實(shí)上面的需求很簡單,如果我們使用JAVA IO體系中的RandomAccessFile類來完成的話,可以實(shí)現(xiàn)零內(nèi)存追加。其實(shí)這就是支持任意位置讀寫類的強(qiáng)大之處。



在這之前,散仙還是喜歡先啰嗦的介紹下RandomAccessFile這個(gè)類,RandomAccessFile是Java中輸入,輸出流體系中功能最豐富的文件內(nèi)容訪問類,它提供很多方法來操作文件,包括讀寫支持,與普通的IO流相比,它最大的特別之處就是支持任意訪問的方式,程序可以直接跳到任意地方來讀寫數(shù)據(jù)。

如果我們只希望訪問文件的部分內(nèi)容,而不是把文件從頭讀到尾,使用RandomAccessFile將會(huì)帶來更簡潔的代碼以及更好的性能。


下面來看下RandomAccessFile類中比較重要的2個(gè)方法,其他的和普通IO類似,在這里,就不詳細(xì)說明了。

方法名 作用
getFilePointer() 返回文件記錄指針的當(dāng)前位置
seek(long pos) 將文件記錄指針定位到pos的位置



下面散仙給出示例,分析下怎么使用RandomAccessFile
首先,我們先看下散仙要操作的文本文件的內(nèi)容截圖。



功能one,讀取任意位置的數(shù)據(jù),代碼如下
Java代碼  收藏代碼
  1. /** 
  2.      * 讀的方法 
  3.      * @param path 文件路徑 
  4.      * @param pointe 指針位置 
  5.      * **/  
  6.     public static void randomRed(String path,int pointe){  
  7.         try{  
  8.             //RandomAccessFile raf=new RandomAccessFile(new File("D:\\3\\test.txt"), "r");  
  9.             /** 
  10.              * model各個(gè)參數(shù)詳解 
  11.              * r 代表以只讀方式打開指定文件 
  12.              * rw 以讀寫方式打開指定文件 
  13.              * rws 讀寫方式打開,并對(duì)內(nèi)容或元數(shù)據(jù)都同步寫入底層存儲(chǔ)設(shè)備 
  14.              * rwd 讀寫方式打開,對(duì)文件內(nèi)容的更新同步更新至底層存儲(chǔ)設(shè)備 
  15.              *  
  16.              * **/  
  17.             RandomAccessFile raf=new RandomAccessFile(path, "r");  
  18.             //獲取RandomAccessFile對(duì)象文件指針的位置,初始位置是0  
  19.             System.out.println("RandomAccessFile文件指針的初始位置:"+raf.getFilePointer());  
  20.             raf.seek(pointe);//移動(dòng)文件指針位置  
  21.             byte[]  buff=new byte[1024];  
  22.             //用于保存實(shí)際讀取的字節(jié)數(shù)  
  23.             int hasRead=0;  
  24.             //循環(huán)讀取  
  25.             while((hasRead=raf.read(buff))>0){  
  26.                 //打印讀取的內(nèi)容,并將字節(jié)轉(zhuǎn)為字符串輸入  
  27.                 System.out.println(new String(buff,0,hasRead));  
  28.                   
  29.             }  
  30.               
  31.               
  32.               
  33.         }catch(Exception e){  
  34.             e.printStackTrace();  
  35.         }  
  36.           
  37.           
  38.           
  39.     }  


測試代碼
Java代碼  收藏代碼
  1. public static void main(String[] args) {  
  2.     String path="D:\\3\\test.txt";         
  3.      int seekPointer=20;  
  4.      randomRed(path,seekPointer);//讀取的方法   
  5.     //randomWrite(path);//追加寫的方法  
  6.     //insert(path, 33, "\nlucene是一個(gè)優(yōu)秀的全文檢索庫");  
  7. }  

運(yùn)行效果:
Java代碼  收藏代碼
  1. RandomAccessFile文件指針的初始位置:0  
  2. is a teacher  
  3. hadoop is perfect  

功能two,追加數(shù)據(jù),代碼如下
Java代碼  收藏代碼
  1. /** 
  2.  * 追加方式 
  3.  * 寫的方法 
  4.  * @param path 文件路徑 
  5.  * ***/  
  6. public static void randomWrite(String path){  
  7.     try{  
  8.         /**以讀寫的方式建立一個(gè)RandomAccessFile對(duì)象**/  
  9.         RandomAccessFile raf=new RandomAccessFile(path, "rw");  
  10.           
  11.         //將記錄指針移動(dòng)到文件最后  
  12.         raf.seek(raf.length());  
  13.         raf.write("我是追加的 \r\n".getBytes());  
  14.           
  15.     }catch(Exception e){  
  16.         e.printStackTrace();  
  17.     }  
  18.       
  19. }  

測試代碼
Java代碼  收藏代碼
  1. public static void main(String[] args) {  
  2.     String path="D:\\3\\test.txt";         
  3.      //int seekPointer=20;  
  4.     // randomRed(path,seekPointer);//讀取的方法   
  5.      randomWrite(path);//追加寫的方法  
  6.     //insert(path, 33, "\nlucene是一個(gè)優(yōu)秀的全文檢索庫");  
  7. }  

運(yùn)行效果:


功能three,任意位置插入數(shù)據(jù),代碼如下
Java代碼  收藏代碼
  1. /** 
  2.      * 實(shí)現(xiàn)向指定位置 
  3.      * 插入數(shù)據(jù) 
  4.      * @param fileName 文件名 
  5.      * @param points 指針位置 
  6.      * @param insertContent 插入內(nèi)容 
  7.      * **/  
  8.     public static void insert(String fileName,long points,String insertContent){  
  9.         try{  
  10.         File tmp=File.createTempFile("tmp", null);  
  11.         tmp.deleteOnExit();//在JVM退出時(shí)刪除  
  12.           
  13.         RandomAccessFile raf=new RandomAccessFile(fileName, "rw");  
  14.         //創(chuàng)建一個(gè)臨時(shí)文件夾來保存插入點(diǎn)后的數(shù)據(jù)  
  15.         FileOutputStream tmpOut=new FileOutputStream(tmp);  
  16.         FileInputStream tmpIn=new FileInputStream(tmp);  
  17.         raf.seek(points);  
  18.         /**將插入點(diǎn)后的內(nèi)容讀入臨時(shí)文件夾**/  
  19.           
  20.         byte [] buff=new byte[1024];  
  21.         //用于保存臨時(shí)讀取的字節(jié)數(shù)  
  22.         int hasRead=0;  
  23.         //循環(huán)讀取插入點(diǎn)后的內(nèi)容  
  24.         while((hasRead=raf.read(buff))>0){  
  25.             // 將讀取的數(shù)據(jù)寫入臨時(shí)文件中  
  26.             tmpOut.write(buff, 0, hasRead);  
  27.         }  
  28.           
  29.         //插入需要指定添加的數(shù)據(jù)  
  30.         raf.seek(points);//返回原來的插入處  
  31.         //追加需要追加的內(nèi)容  
  32.         raf.write(insertContent.getBytes());  
  33.         //最后追加臨時(shí)文件中的內(nèi)容  
  34.         while((hasRead=tmpIn.read(buff))>0){  
  35.             raf.write(buff,0,hasRead);  
  36.         }  
  37.         }catch(Exception e){  
  38.             e.printStackTrace();  
  39.         }  
  40.     }  

測試代碼
Java代碼  收藏代碼
  1. public static void main(String[] args) {  
  2.         String path="D:\\3\\test.txt";         
  3.          //int seekPointer=20;  
  4.         // randomRed(path,seekPointer);//讀取的方法   
  5.         // randomWrite(path);//追加寫的方法  
  6.          insert(path, 33, "\nlucene是一個(gè)優(yōu)秀的全文檢索庫");  
  7.     }  

運(yùn)行效果:



至此,RandomAccessFile類的幾個(gè)功能,散仙在代碼中已給出實(shí)現(xiàn)了,現(xiàn)在回到本文開始前的提的那個(gè)需求,用RandomAccessFile類就可以輕而易舉的完成了,另外需要注意的是,向指定位置插入數(shù)據(jù),是散仙自己改造的功能,RandomAccessFile并不直接支持,需要新建一個(gè)緩沖區(qū)臨時(shí)空間,存數(shù)據(jù),然后在寫,因?yàn)橐坏?shù)據(jù)量上了級(jí)別,在任意位置插入數(shù)據(jù),是很耗內(nèi)存的,這個(gè)也就是為什么hadoop的HDFS文件系統(tǒng),只支持append的方式,而沒有提供修改的操作。


另外我們可以用RandomAccessFile這個(gè)類,來實(shí)現(xiàn)一個(gè)多線程斷點(diǎn)下載的功能,用過下載工具的朋友們都知道,下載前都會(huì)建立兩個(gè)臨時(shí)文件,一個(gè)是與被下載文件大小相同的空文件,另一個(gè)是記錄文件指針的位置文件,每次暫停的時(shí)候,都會(huì)保存上一次的指針,然后斷點(diǎn)下載的時(shí)候,會(huì)繼續(xù)從上一次的地方下載,從而實(shí)現(xiàn)斷點(diǎn)下載或上傳的功能,有興趣的朋友們可以自己實(shí)現(xiàn)下。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多