2018-04-24

RandomAcessFile類基本使用詳解



目錄

1、構(gòu)造函數(shù)
2葫督、常用的方法
--2.1、最基本的方法----read()和write()
--2.2橄镜、其他的讀寫方法
3、RandomAcessFile文件復(fù)制



java.io.RandomAcessFile可以對(duì)文件進(jìn)行隨機(jī)的讀取和寫入洽胶。

1、構(gòu)造函數(shù)

//創(chuàng)建從中讀取和向其中寫入的隨機(jī)訪問文件流姊氓,該文件由File參數(shù)指定
public RandomAcessFile(File file,String mode);

//創(chuàng)建從中讀取和向其中寫入的隨機(jī)訪問文件流,該文件具有指定的名稱
public RandomAccessFile(String name,String mode);

參數(shù)說明:

r:read w:write s:synchronously d:device

mode:

r :以只讀方式打開

rw :以讀寫方式打開(如果使用的是上面的第一個(gè)構(gòu)造函數(shù)他膳,如果該文件不存在绒窑,則嘗試創(chuàng)建該文件)

rws:以讀寫方式打開,還要求對(duì)文件的內(nèi)容或元數(shù)據(jù)的每個(gè)更新都同步寫入到底層存儲(chǔ)設(shè)備。 rws模式是同步模式蟀俊,你每寫入一個(gè)字節(jié)的數(shù)據(jù),數(shù)據(jù)就立馬寫入到設(shè)備上面,可以保證由該調(diào)用對(duì)此文件所做的所有更改均被寫入該設(shè)備肢预。這對(duì)確保在系統(tǒng)崩潰時(shí)不會(huì)丟失重要信息特別有用。

rwd:以讀寫方式打開烫映,還要求對(duì)文件的內(nèi)容的每個(gè)更新都同步寫入到底層存儲(chǔ)設(shè)備沼本。rwd模式可用于減少執(zhí)行的 I/O 操作數(shù)量。

使用 rwd 僅要求更新要寫入存儲(chǔ)的文件的內(nèi)容锭沟;使用 rws 要求更新要寫入的文件內(nèi)容及其元數(shù)據(jù)抽兆,這通常要求至少一個(gè)以上的低級(jí)別 I/O 操作。

2族淮、常用的方法

2.1辫红、最基本的方法----read()和write()

//從此文件中讀取一個(gè)數(shù)據(jù)字節(jié)(8bit)
public int read();

//向此文件中寫入一個(gè)數(shù)據(jù)字節(jié)(8bit)
public int write(int b);

我們都知道在Java中int占4個(gè)字節(jié)(32bit),如果我們要將一個(gè)int數(shù)據(jù)寫入到文件中那么每次只能寫入1個(gè)字節(jié),就意味著我們必須要將int型數(shù)據(jù)拆分為4次來寫入到文件中祝辣,同樣的贴妻,在讀取數(shù)據(jù)的時(shí)候也是一樣的。

import java.io.File;
import java.io.RandomAccessFile;

/**
 * RandomAccessFile隨機(jī)訪問文件的讀取和寫入
 * 在這里我們new兩個(gè)RandomAccessFile的實(shí)例出來蝙斜,一個(gè)用來向文件中存入數(shù)據(jù)名惩,另一個(gè)用來讀取文件中的數(shù)據(jù),假設(shè)demo.dat文件已經(jīng)存在
 * @author Administrator
 *
 */
public class RandomAccessFileDemo01 {
    public static void main(String[] args){
        try {
            //構(gòu)造方法一乍炉,該實(shí)例用來向文件中寫入數(shù)據(jù)
            RandomAccessFile raf=new RandomAccessFile("demo.dat", "rw");
            //構(gòu)造方法二绢片,該實(shí)例用來讀取文件中的數(shù)據(jù)
            File file=new File("demo.dat");
            RandomAccessFile raf1=new RandomAccessFile(file, "rw");
            
            /**
             * public void write(int b)throws IOException
             * 每次只寫入一個(gè)字節(jié),寫入整數(shù)的"低8位"
             */
            int x=999999999;//二進(jìn)制表示為:00111011 10011010 11001001 11111111
            raf.write((x>>>24)&0xff);//寫入高8位:00111011
            System.out.println(Integer.toBinaryString((x>>>24)&0xff));
            raf.write(x>>>16&0xff);//寫入中上8位:10011010
            System.out.println(Integer.toBinaryString((x>>>16)&0xff));
            raf.write(x>>>8&0xff);//寫入中下8位:11001001
            System.out.println(Integer.toBinaryString((x>>>8)&0xff));
            raf.write(x);//寫入低8位置:11111111
            System.out.println(Integer.toBinaryString((x>>>0)&0xff));
            raf.close();
            
            
            /**
             * 從當(dāng)前文件中讀取一個(gè)字節(jié)岛琼,將該字節(jié)存入返回的int中
             * 若返回值為-1底循,則說明讀取到了文件的末尾(EOF:END OF FILE)
             */
            int a=raf1.read();
            int b=raf1.read();
            int c=raf1.read();
            int d=raf1.read();
            //將每次讀取出來的數(shù)據(jù)依次算術(shù)移位
            int readX=(a<<24)+(b<<16)+(c<<8)+(d);
            System.out.println("讀取出來的數(shù)據(jù)為:"+readX);
            raf1.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}

有人會(huì)說這樣做好麻煩啊槐瑞!是的熙涤,這樣做確實(shí)是很麻煩,強(qiáng)大的Java已經(jīng)給我們封裝好了其他的方法了困檩,但是祠挫,我們通過查看源碼可以知道其他已經(jīng)封裝好的方法都是以上面所述的方法為基礎(chǔ)的。

2.2悼沿、其他的讀寫方法:

//將最多 b.length 個(gè)數(shù)據(jù)字節(jié)從此文件讀入 byte 數(shù)組
public int read(byte[] b);
//將 b.length 個(gè)字節(jié)從指定 byte 數(shù)組寫入到此文件
public void write(byte[] b);

//最多 len 個(gè)數(shù)據(jù)字節(jié)從此文件讀入 byte 數(shù)組,off是寫入數(shù)據(jù)時(shí)字節(jié)數(shù)組b中的初始偏移量
public int read(byte[] b,int off,int len);
//將 len 個(gè)字節(jié)從指定 byte 數(shù)組寫入到此文件等舔,并從偏移量 off 處開始
public void write(byte[] b,int off,int len);

//從此文件讀取一個(gè) boolean。此方法從該文件的當(dāng)前文件指針開始讀取單個(gè)字節(jié)糟趾。值 0 表示 false慌植。其他任何值表示 true
public final boolean readBoolean();
//按單字節(jié)值將 boolean 寫入該文件
public final void writeBoolean(boolean v);

//從此文件讀取一個(gè)有符號(hào)的八位值甚牲。此方法從該文件的當(dāng)前文件指針開始讀取一個(gè)字節(jié)
public final byte readByte();
//按單字節(jié)值將 byte 寫入該文件
public final void writeByte(int v);
//按字節(jié)序列將該字符串寫入該文件。該字符串中的每個(gè)字符均按順序?qū)懗龅粒G棄其高八位
public final void writeBytes(String s);


//從此文件讀取一個(gè)字符丈钙。此方法從該文件的當(dāng)前文件指針開始讀取兩個(gè)字節(jié)
public final char readChar();
//按雙字節(jié)值將 char 寫入該文件,先寫高字節(jié)
public final void writeChar(int v);
//按字符序列將一個(gè)字符串寫入該文件交汤。每個(gè)字符均寫入數(shù)據(jù)輸出流
public final void writeChars(String s);

//從此文件讀取一個(gè) double
public final double readDouble();
//使用 Double 類中的 doubleToLongBits 方法將雙精度參數(shù)轉(zhuǎn)換為一個(gè) long雏赦,然后按八字節(jié)數(shù)量將該 long 值寫入該文件,先定高字節(jié)
public final void writeDouble(double v);

//從此文件讀取一個(gè) float
public final float readFloat();
//使用 Float 類中的 floatToIntBits 方法將浮點(diǎn)參數(shù)轉(zhuǎn)換為一個(gè) int星岗,然后按四字節(jié)數(shù)量將該 int 值寫入該文件伍茄,先寫高字節(jié)
public final void writeFloat(float v);

//從此文件讀取一個(gè)有符號(hào)的 32 位整數(shù)施逾。此方法從該文件的當(dāng)前文件指針開始讀取 4 個(gè)字節(jié)
public final int readInt();
//按四個(gè)字節(jié)將 int 寫入該文件汉额,先寫高字節(jié)
public final void writeInt(int v);

//從此文件讀取一個(gè)有符號(hào)的 64 位整數(shù)蠕搜。此方法從該文件的當(dāng)前文件指針開始讀取八個(gè)字節(jié)
public final long readLong();
//按八個(gè)字節(jié)將 long 寫入該文件妓灌,先寫高字節(jié)
public final void writeLong(long v);

以上基本上就是RandomAcessFile類所有的讀寫方法

3虫埂、RandomAcessFile文件復(fù)制:

import java.io.RandomAccessFile;

public class RandomAccessFileDemo02 {

    public static void main(String[] args) {
        /**
         * 案例:兩個(gè)文件之間的復(fù)制
         * 1.先new一個(gè)RandomAcessFile用來讀取文件里面的數(shù)據(jù)
         * 2.繼續(xù)new一個(gè)RandomAcessFile用戶寫入讀取到的數(shù)據(jù)
         * 3.直到讀取數(shù)據(jù)的返回值為-1時(shí)則說明讀取完畢
         */
        try {
            //可以使用大概5MB大小的文件來測(cè)試
            long begin=System.currentTimeMillis();
            RandomAccessFile  src=new RandomAccessFile("src.txt", "rw");
            RandomAccessFile dest=new RandomAccessFile("dest.txt", "rw");
            
            /**
             * 按一個(gè)字節(jié)一個(gè)字節(jié)的讀取
             * 按一個(gè)字節(jié)一個(gè)字節(jié)的寫入
             * 
             */
            int flag=0;
            while((flag=src.read())!=-1){
                dest.write(flag);
            }
            if(flag==-1){
                System.out.println("文件復(fù)制成功掉伏!");
            }else{
                System.out.println("文件復(fù)制失敻ⅰ鸡捐!");
            }
            src.close();
            dest.close();
            long end=System.currentTimeMillis();
            System.out.println("按字節(jié)讀寫的時(shí)間為:"+(end-begin));
            /**
             * 使用字節(jié)數(shù)組來讀取和寫入
             */
            
            long begin1=System.currentTimeMillis();
            RandomAccessFile  src1=new RandomAccessFile("src1.txt", "rw");
            RandomAccessFile dest1=new RandomAccessFile("dest1.txt", "rw");
            //建立一個(gè)文件緩沖區(qū)箍镜,每次讀取buffer.length大小的數(shù)據(jù)
            byte[] buffer=new byte[1024*8];
            int flag1=0;
            //每一次循環(huán)讀寫的數(shù)據(jù)量為1024*8個(gè)字節(jié)的數(shù)組,返回值為實(shí)際讀到的字節(jié)數(shù)
            while((flag1=src1.read(buffer))!=-1){
                dest1.write(buffer);
            }
            if(flag1==-1){
                System.out.println("文件復(fù)制成功鹿寨!");
            }else{
                System.out.println("文件復(fù)制失斀挪荨馏慨!");
            }
            src1.close();
            dest1.close();
            long end1=System.currentTimeMillis();
            System.out.println("按字節(jié)數(shù)組讀寫的時(shí)間為:"+(end1-begin1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

運(yùn)行結(jié)果:

文件復(fù)制成功!

按字節(jié)讀寫的時(shí)間為:22148

文件復(fù)制成功倔撞!

按字節(jié)數(shù)組讀寫的時(shí)間為:12

以上的數(shù)據(jù)說明痪蝇,我們?nèi)绻岣呶募淖x寫效率,那么就要減少I/O的次數(shù)躏啰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末给僵,一起剝皮案震驚了整個(gè)濱河市帝际,隨后出現(xiàn)的幾起案子饶辙,更是在濱河造成了極大的恐慌畸悬,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異冷冗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)拇泛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門俺叭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熄守,“玉大人,你說我怎么就攤上這事裕照〗希” “怎么了负间?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)餐屎。 經(jīng)常有香客問我,道長(zhǎng)空扎,這世上最難降的妖魔是什么润讥? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任楚殿,我火速辦了婚禮,結(jié)果婚禮上砌溺,老公的妹妹穿的比我還像新娘变隔。我一直安慰自己匣缘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布培慌。 她就那樣靜靜地躺著,像睡著了一般盒音。 火紅的嫁衣襯著肌膚如雪里逆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音偎血,去河邊找鬼颇玷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谒亦,可吹牛的內(nèi)容都是我干的份招。 我是一名探鬼主播锁摔,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼哼审,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼涩盾!你這毒婦竟也來了春霍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤籍胯,失蹤者是張志新(化名)和其女友劉穎杖狼,沒想到半個(gè)月后蝶涩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗽上,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挪圾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哲思。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖帝簇,靈堂內(nèi)的尸體忽然破棺而出己儒,到底是詐尸還是另有隱情捆毫,我是刑警寧澤绩卤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布江醇,位于F島的核電站濒憋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏陶夜。R本人自食惡果不足惜凛驮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望条辟。 院中可真熱鬧黔夭,春花似錦宏胯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至婚惫,卻和暖如春氛赐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背艰管。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工街图, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人絮姆。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓鸽照,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子峡谊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容