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
:readw
:writes
:synchronouslyd
: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ù)躏啰。