管道流
管道流的輸入輸出流可以直接連接动看,通過結(jié)合線程來使用。
(Properties是IO與集合的結(jié)合爪幻,而管道流是IO與線程的結(jié)合)
PipedInputStream:
構(gòu)造函數(shù):
PipedInputStream() 創(chuàng)建一個(gè) PipedInputStream 菱皆,所以它還不是 connected 。 PipedInputStream(int pipeSize) 創(chuàng)建一個(gè) PipedInputStream 挨稿,使其尚未 connected 仇轻,并使用指定的管道大小作為管道的緩沖區(qū)。
PipedInputStream(PipedOutputStream src) 創(chuàng)建一個(gè) PipedInputStream 奶甘,使其連接到管道輸出流 src 篷店。
PipedInputStream(PipedOutputStream src, int pipeSize) 創(chuàng)建一個(gè) PipedInputStream ,使其連接到管道輸出流 src ,并為管道緩沖區(qū)使用指定的管道大小疲陕。
API:
void connect(PipedOutputStream src) 使此管道輸入流連接到管道輸出流 src 方淤。連接方法,輸入輸出流都有蹄殃,只要一個(gè)調(diào)用即可携茂。
PipedOutputStream:
構(gòu)造函數(shù):
PipedOutputStream() 創(chuàng)建一個(gè)尚未連接到管道輸入流的管道輸出流。 PipedOutputStream(PipedInputStream snk) 創(chuàng)建連接到指定管道輸入流的管道輸出流诅岩。
RandomAccessFile
RandomAccessFile:隨機(jī)訪問文件讳苦,自身具備讀寫的方法。內(nèi)部封裝了一個(gè)byte數(shù)組吩谦,通過指針對(duì)數(shù)組的元素進(jìn)行操作鸳谜。
通過skipBytes(int x),seek(int x)來達(dá)到隨機(jī)訪問式廷。
通過getFilePointer獲取指針的位置咐扭。
(能完成讀寫的原理是,其內(nèi)部封裝了字節(jié)輸入流和輸出流)
構(gòu)造函數(shù):
rw如果文件不存在懒棉,會(huì)創(chuàng)建文件草描,如果存在,不會(huì)覆蓋策严。
r如果文件不存在穗慕,不會(huì)創(chuàng)建文件
RandomAccessFile(File file, String mode) 創(chuàng)建一個(gè)隨機(jī)訪問文件流從File參數(shù)指定的文件中讀取,并可選地寫入文件妻导。
RandomAccessFile(String name, String mode) 創(chuàng)建隨機(jī)訪問文件流逛绵,以從中指定名稱的文件讀取,并可選擇寫入文件倔韭。
mode:
1 r:以只讀方式打開指定文件术浪。如果試圖對(duì)該RandomAccessFile指定的文件執(zhí)行寫入方法則會(huì)拋出IOException
2 rw:以讀取、寫入方式打開指定文件寿酌。如果該文件不存在胰苏,則嘗試創(chuàng)建文件
3 rws(了解):以讀取、寫入方式打開指定文件醇疼。相對(duì)于rw模式硕并,還要求對(duì)文件的內(nèi)容或元數(shù)據(jù)的每個(gè)更新都同步寫入到底層存儲(chǔ)設(shè)備,默認(rèn)情形下(rw模式下),是使用buffer的,只有cache滿的或者使用RandomAccessFile.close()關(guān)閉流的時(shí)候兒才真正的寫到文件
4 rwd(了解):與rws類似秧荆,只是僅對(duì)文件的內(nèi)容同步更新到磁盤倔毙,而不修改文件的元數(shù)據(jù)
API:
void write(int b) 將指定的字節(jié)寫入此文件。
void writeInt(int v) 將 int寫入文件為四個(gè)字節(jié)乙濒,高字節(jié) int 陕赃。
void write(byte[] b) 從指定的字節(jié)數(shù)組寫入 b.length個(gè)字節(jié)到該文件,從當(dāng)前文件指針開始。
小例子演示:
public class Demo11 {
public static void main(String[] args) throws Exception{
writeFile();
}
public static void writeFile() throws Exception{
File file = new File("D:\\a.txt");
if(file.exists())
file.delete();
RandomAccessFile raf = new RandomAccessFile("D:\\a.txt","rw");
raf.write("張三".getBytes());
raf.write(97);
raf.close();
}
}
發(fā)現(xiàn)a.txt有7個(gè)字節(jié)么库,內(nèi)容是:張三a
其中raf.write("張三".getBytes());調(diào)用的是write(byte[] b) 傻丝,getBytes根據(jù)java本身的unicode編碼轉(zhuǎn)換為系統(tǒng)默認(rèn)的utf-8編碼后,為3個(gè)字節(jié)诉儒,所以張三兩個(gè)字占了6個(gè)字節(jié)桑滩,而raf.write(97);調(diào)用的是write(int b),雖然int類型有4個(gè)字節(jié)允睹,但是該方法只寫入最低的8位,所以當(dāng)int類型的值超過了8位時(shí)幌氮,進(jìn)行寫入操作就會(huì)丟失數(shù)據(jù)缭受。此時(shí)就要使用writeInt方法。
比如该互,使用write方法得到的文件如下:
而此時(shí)使用writeInt再寫一遍:
兩次寫操作米者,對(duì)于字符的編碼都是一樣的,采用Unicode碼轉(zhuǎn)換為utf-8的三位字節(jié)宇智,而區(qū)別就是int類型寫入了一個(gè)字節(jié)和四個(gè)字節(jié)蔓搞。
=========================================
int readInt() 從該文件讀取一個(gè)帶符號(hào)的32位整數(shù)。
使用了writeInt之后随橘,使用readInt來讀取喂分,非常方便。
這兩個(gè)方法是這個(gè)類的精髓机蔗。
int skipBytes(int n) 嘗試跳過 n字節(jié)的輸入丟棄跳過的字節(jié)
void seek(long pos) 設(shè)置文件指針偏移蒲祈,從該文件的開頭測(cè)量,發(fā)生下一次讀取或?qū)懭搿?br>
區(qū)別:
skipBytes只能往下跳萝嘁,而seek可以隨意調(diào)整文件指針的位置梆掸,更加靈活
小例子:
現(xiàn)有文本文件如下:
要求不讀取李四和b,直接讀取王五和后面的int牙言。
public class Demo11 {
public static void main(String[] args) throws Exception{
skipReadFile();
}
public static void skipReadFile() throws Exception{
RandomAccessFile raf = new RandomAccessFile("D:\\A1.txt","r");
raf.skipBytes(10);
byte[] buf = new byte[6];
raf.read(buf);
System.out.println("名字:" + new String(buf));
System.out.println("age:" + raf.readInt());
}
}
小例子2:
不覆蓋現(xiàn)有數(shù)據(jù)酸钦,在現(xiàn)有數(shù)據(jù)之后進(jìn)行續(xù)寫。
public static void seekWriteFile() throws Exception{
RandomAccessFile raf = new RandomAccessFile("D:\\A1.txt","rw");
raf.seek(10*2);
raf.write("周七".getBytes());
raf.writeInt(103);
}
RandomAccessFile應(yīng)用:多線程共同寫入數(shù)據(jù)而不會(huì)沖突咱枉。
DataStream
用于操作基本數(shù)據(jù)類型的流對(duì)象卑硫。
DataInputStream
構(gòu)造函數(shù):
DataInputStream(InputStream in) 創(chuàng)建使用指定的底層InputStream的DataInputStream。
API:
int readInt() 見 readInt方法 DataInput的一般合同庞钢。
String readUTF() 見 readUTF法 DataInput的一般合同拔恰。String readUTF() 見 readUTF法 DataInput的一般合同。
DataOutputStream
構(gòu)造函數(shù):
DataOutputStream(OutputStream out) 創(chuàng)建一個(gè)新的數(shù)據(jù)輸出流基括,以將數(shù)據(jù)寫入指定的底層輸出流颜懊。
API:
void writeInt(int v) 將底層輸出流寫入 int作為四字節(jié),高位字節(jié)。
有各種操作基本數(shù)據(jù)類型的方法河爹。
void writeUTF(String str) 使用 modified UTF-8編碼以機(jī)器無關(guān)的方式將字符串寫入基礎(chǔ)輸出流匠璧。
小例子:
public class Demo12 {
public static void main(String[] args) throws IOException{
// writeData();
readData();
}
public static void readData() throws IOException{
DataInputStream dataInput = new DataInputStream(new FileInputStream("D:\\dataOutput.txt"));
System.out.println(dataInput.readInt());
}
public static void writeData() throws IOException{
DataOutputStream dataOutput = new DataOutputStream(new FileOutputStream("D:\\dataOutput.txt"));
dataOutput.writeInt(32);
dataOutput.flush();
dataOutput.close();
}
}