日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

java 文件随机读取_Java 实现文件随机读写-RandomAccessFile

發(fā)布時(shí)間:2025/3/20 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 文件随机读取_Java 实现文件随机读写-RandomAccessFile 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

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

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

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

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

方法名

作用

getFilePointer()

返回文件記錄指針的當(dāng)前位置

seek(long pos)

將文件記錄指針定位到pos的位置

下面散仙給出示例,分析下怎么使用RandomAccessFile

首先,我們先看下要操作的文本文件的內(nèi)容截圖。

功能one,讀取任意位置的數(shù)據(jù),代碼如下

Java代碼 ?

/**

*?讀的方法

*?@param?path?文件路徑

*?@param?pointe?指針位置

*?**/

public?static?void?randomRed(String?path,int?pointe){

try{

//RandomAccessFile?raf=new?RandomAccessFile(new?File("D:\\3\\test.txt"),?"r");

/**

*?model各個(gè)參數(shù)詳解

*?r?代表以只讀方式打開指定文件

*?rw?以讀寫方式打開指定文件

*?rws?讀寫方式打開,并對(duì)內(nèi)容或元數(shù)據(jù)都同步寫入底層存儲(chǔ)設(shè)備

*?rwd?讀寫方式打開,對(duì)文件內(nèi)容的更新同步更新至底層存儲(chǔ)設(shè)備

*

*?**/

RandomAccessFile?raf=new?RandomAccessFile(path,?"r");

//獲取RandomAccessFile對(duì)象文件指針的位置,初始位置是0

System.out.println("RandomAccessFile文件指針的初始位置:"+raf.getFilePointer());

raf.seek(pointe);//移動(dòng)文件指針位置

byte[]??buff=new?byte[1024];

//用于保存實(shí)際讀取的字節(jié)數(shù)

int?hasRead=0;

//循環(huán)讀取

while((hasRead=raf.read(buff))>0){

//打印讀取的內(nèi)容,并將字節(jié)轉(zhuǎn)為字符串輸入

System.out.println(new?String(buff,0,hasRead));

}

}catch(Exception?e){

e.printStackTrace();

}

}

測(cè)試代碼

Java代碼 ?

public?static?void?main(String[]?args)?{

String?path="D:\\3\\test.txt";

int?seekPointer=20;

randomRed(path,seekPointer);//讀取的方法

//randomWrite(path);//追加寫的方法

//insert(path,?33,?"\nlucene是一個(gè)優(yōu)秀的全文檢索庫(kù)");

}

運(yùn)行效果:

Java代碼 ?

RandomAccessFile文件指針的初始位置:0

is?a?teacher

hadoop?is?perfect

功能two,追加數(shù)據(jù),代碼如下

Java代碼 ?

/**

*?追加方式

*?寫的方法

*?@param?path?文件路徑

*?***/

public?static?void?randomWrite(String?path){

try{

/**以讀寫的方式建立一個(gè)RandomAccessFile對(duì)象**/

RandomAccessFile?raf=new?RandomAccessFile(path,?"rw");

//將記錄指針移動(dòng)到文件最后

raf.seek(raf.length());

raf.write("我是追加的?\r\n".getBytes());

}catch(Exception?e){

e.printStackTrace();

}

}

測(cè)試代碼

Java代碼 ?

public?static?void?main(String[]?args)?{

String?path="D:\\3\\test.txt";

//int?seekPointer=20;

//?randomRed(path,seekPointer);//讀取的方法

randomWrite(path);//追加寫的方法

//insert(path,?33,?"\nlucene是一個(gè)優(yōu)秀的全文檢索庫(kù)");

}

運(yùn)行效果:

功能three,任意位置插入數(shù)據(jù),代碼如下

Java代碼 ?

/**

*?實(shí)現(xiàn)向指定位置

*?插入數(shù)據(jù)

*?@param?fileName?文件名

*?@param?points?指針位置

*?@param?insertContent?插入內(nèi)容

*?**/

public?static?void?insert(String?fileName,long?points,String?insertContent){

try{

File?tmp=File.createTempFile("tmp",?null);

tmp.deleteOnExit();//在JVM退出時(shí)刪除

RandomAccessFile?raf=new?RandomAccessFile(fileName,?"rw");

//創(chuàng)建一個(gè)臨時(shí)文件夾來(lái)保存插入點(diǎn)后的數(shù)據(jù)

FileOutputStream?tmpOut=new?FileOutputStream(tmp);

FileInputStream?tmpIn=new?FileInputStream(tmp);

raf.seek(points);

/**將插入點(diǎn)后的內(nèi)容讀入臨時(shí)文件夾**/

byte?[]?buff=new?byte[1024];

//用于保存臨時(shí)讀取的字節(jié)數(shù)

int?hasRead=0;

//循環(huán)讀取插入點(diǎn)后的內(nèi)容

while((hasRead=raf.read(buff))>0){

//?將讀取的數(shù)據(jù)寫入臨時(shí)文件中

tmpOut.write(buff,?0,?hasRead);

}

//插入需要指定添加的數(shù)據(jù)

raf.seek(points);//返回原來(lái)的插入處

//追加需要追加的內(nèi)容

raf.write(insertContent.getBytes());

//最后追加臨時(shí)文件中的內(nèi)容

while((hasRead=tmpIn.read(buff))>0){

raf.write(buff,0,hasRead);

}

}catch(Exception?e){

e.printStackTrace();

}

}

測(cè)試代碼

Java代碼 ?

public?static?void?main(String[]?args)?{

String?path="D:\\3\\test.txt";

//int?seekPointer=20;

//?randomRed(path,seekPointer);//讀取的方法

//?randomWrite(path);//追加寫的方法

insert(path,?33,?"\nlucene是一個(gè)優(yōu)秀的全文檢索庫(kù)");

}

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

總結(jié)

以上是生活随笔為你收集整理的java 文件随机读取_Java 实现文件随机读写-RandomAccessFile的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。