- 相關(guān)推薦
java io流學(xué)習總結
一、什么是流?
流就是字節序列的抽象概念,能被連續讀取數據的數據源和能被連續寫(xiě)入數據的接收端就是流,流機制是Java及C++中的一個(gè)重要機制,通過(guò)流我們可以自由地控制文件、內存、IO設備等數據的流向。而IO流就是用于處理設備上的數據,如:硬盤(pán)、內存、鍵盤(pán)錄入等。IO流根據處理類(lèi)型的不同可分為字節流和字符流,根據流向的不同可分為輸入流和輸出流。
二、字節流和字符流的區別:
字符流,因為文件編碼的不同,就有了對字符進(jìn)行高效操作的字符流對象,它的原理就是基于字節流讀取字節時(shí)去查了指定的碼表。它和字節流的區別有兩點(diǎn):1.在讀取數據的時(shí)候,字節流讀到一個(gè)字節就返回一個(gè)字節,字符流使用了字節流讀到一個(gè)或多個(gè)字節(一個(gè)中文對應的字節數是兩個(gè),在UTF-8碼表中是3個(gè)字節)時(shí),先去查指定的編碼表,再將查到的字符返回;2.字節流可以處理所有類(lèi)型的數據,如jpg、avi、mp3、wav等等,而字符流只能處理字符數據。所以可以根據處理的文件不同考慮使用字節流還是字符流,如果是純文本數據可以?xún)?yōu)先考慮字符流,否則使用字節流。
三、IO體系,所具備的基本功能就是讀和寫(xiě):
1.字符流
|-- Reader(讀)
|-- Writer(寫(xiě))
Reader
|--InputStreamReader
|--FileReader:用于處理文件的字符讀取流對象
Writer
|--OutputStreamWriter
|--FileWriter:用于處理文件的字符寫(xiě)入流對象
其實(shí)很容易就可以看出來(lái),IO體系中的子類(lèi)名后綴絕大部分是父類(lèi)名稱(chēng),而前綴則是體現子類(lèi)特有功能的名稱(chēng)。
Reader中常見(jiàn)的方法:
|--int read()
讀取一個(gè)字符,并返回讀到的這個(gè)字符,讀到流的末尾則返回-1。
|--int read(char[])
將讀到的字符存入指定的數組中,返回的是讀到的字符個(gè)數,
讀到流的末尾則返回-1。
|--close()
讀取字符其實(shí)用的是window系統的功能,就希望使用完畢后,
進(jìn)行資源的釋放。
FileReader除了自己的構造函數外沒(méi)有特有的方法:
|--用于讀取文本文件的流對象。
|--用于關(guān)聯(lián)文本文件。
|--構造函數FileReader(String fileName)
在讀取流對象初始化時(shí),必須要指定一個(gè)被讀取的文件,
如果該文件不存在則會(huì )發(fā)生FileNotFoundException異常。
Writer中常見(jiàn)的方法:
|--write()
將一個(gè)字符寫(xiě)入到流中。
|--write(char[])
將一個(gè)字符數組寫(xiě)入到流中。
|--writer(String)
將一個(gè)字符寫(xiě)入到流中。
|--flush()
刷新流,將流中的數據刷新到目的地中,流還存在。
|--close()
關(guān)閉資源,在關(guān)閉錢(qián)會(huì )先調用flush(), 刷新流中的數據到目的地。
FileWriter,除了自己的構造函數外沒(méi)有特有的方法:
|--該類(lèi)的特點(diǎn)
|--用于處理文本文件
|--沒(méi)有默認的編碼表
|--有臨時(shí)緩沖
|--構造函數,在寫(xiě)入流對象初始化時(shí),必須要有一個(gè)存儲數據的目的地。
|--FileWriter(String fileName),該構造器是干什么用的呢?
|--調用系統資源
|--在指定位置創(chuàng )建一個(gè)文件,如果該文件已經(jīng)存在則被覆蓋。
|--FileWriter(String filename,Boolean append),這構造器的作用是?
當傳入的boolean類(lèi)型的值為true時(shí),會(huì )在指定文件末尾處進(jìn)行數據的續寫(xiě)。
清單1,將文本數據保存到文件中代碼
private static void test1(){
FileWriter fw=null;
try {
//初始化FileWriter對象,指定文件名已經(jīng)存儲路徑
fw=new FileWriter("D:/test.txt");
fw.write("將字符串寫(xiě)入流");
//將流中的數據刷新到目的地,流還在
fw.flush();
fw.write("將字符串寫(xiě)入流");
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fw!=null){
try {
fw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
清單2,讀取一個(gè)已有文本文件,并將文本內容打印出來(lái)代碼
private static void test2(){
FileReader fr=null;
try {
//初始化FileReader對象,指定文件路徑
fr=new FileReader("D:/test.txt");
int ch=0;
while((ch=fr.read())!=-1){
//每次讀取一個(gè)字符,直到讀到末尾-1為止
System.out.println((char)ch);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fr!=null){
try {
fr.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
這樣每讀到一個(gè)字符就打印出來(lái),效率很不高,能不能按指定大小讀取完后再打印出來(lái)呢?答案是當然可以的。
清單3,讀取一個(gè)已有文本文件,讀完1kb再將其讀到的內容打印出來(lái)代碼
private static void test3(){
FileReader fr=null;
try {
//初始化FileReader對象,指定文件路徑
fr=new FileReader("D:/test.txt");
char[] buf=new char[1024];
int len=0;
while((len=fr.read(buf))!=-1){
//每次讀取1kb大小的字符,直到讀到末尾-1為止
System.out.println(new String(buf,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fr!=null){
try {
fr.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
字符流的緩沖區:
|--緩沖區的出現提高了對流的操作效率。
原理:其實(shí)就是將數組進(jìn)行封裝。
|--對應的對象
|--BufferedWriter
特有方法newLine(),跨平臺的換行符。
|--BufferedReader
特有方法readLine(),一次讀一行,到行標記時(shí),將行標記
之前的字符數據作為字符串返回,讀到末尾返回null。
|--說(shuō)明
在使用緩沖區對象時(shí),要明確,緩沖的存在是為了增強流
的功能而存在,所以在建立緩沖區對象時(shí),要先有流對象
存在。其實(shí)緩沖區內部就是在使用流對象的方法,只不過(guò)
加入了數組對數據進(jìn)行了臨時(shí)存儲,為了提高操作數據的
效率。
|--代碼上的體現
|--寫(xiě)入緩沖區對象
根據前面所說(shuō)的建立緩沖區時(shí)要先有流對象,并將其作為參數傳遞給緩沖區的構造函數
BufferedWriter bufw=new BufferedWriter(new FileWriter(“test.txt”));
bufw.write(“將數據寫(xiě)入緩沖區”);
bufw.flush();//將緩沖區的數據刷新到目的地
bufw.close();//其實(shí)關(guān)閉的是被包裝在內部的流對象
|--讀取緩沖區對象
BufferedReader bufr=new BufferedReader(new FileReader(“test.txt”));
String line=null;
while((line=bufr.readLine())!=null){
//每次讀取一行,取出的數據不包含回車(chē)符
system.out.println(line);
}
bufr.close();
清單4,使用緩沖區對文本文件進(jìn)行拷貝代碼
private static void test4(){
BufferedReader bufr=null;
BufferedWriter bufw=null;
try {
bufr=new BufferedReader(new FileReader("D:/a.txt"));
bufw=new BufferedWriter(new FileWriter("D:/b.txt"));
String line=null;
while((line=bufr.readLine())!=null){
bufw.write(line);//每次將一行寫(xiě)入緩沖區
bufw.flush();//刷新到目的地
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(bufw!=null){
bufw.close();
}
if(bufr!=null){
bufr.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
仔細看可以發(fā)現,程序里面的FileReader對象和FileWriter對象直接new出來(lái)且沒(méi)有調用close(),因為緩沖對象調用了這兩個(gè)方法,前面說(shuō)了,緩沖對象調用的flush()和close()其實(shí)就是關(guān)閉被包裝在其內部的流對象。關(guān)閉流的先后順序也要注意,如果流之間有依賴(lài)關(guān)系,則被依賴(lài)的流要后關(guān)閉。readLine()方法原理:其實(shí)緩沖區中的該方法,用的還是與緩沖區關(guān)聯(lián)的流對象的read方法,只不過(guò),每一次讀到一個(gè)字符先不進(jìn)行具體操作,先進(jìn)行臨時(shí)存儲,當讀到回車(chē)標記時(shí),將臨時(shí)容器中存儲的數據一次性返回。我們可以根據這個(gè)原理來(lái)自己編寫(xiě)一個(gè)緩沖區對象。
清單5,編寫(xiě)一個(gè)自己的bufferedreader代碼
public class MyBufferedReader {
private Reader reader;
public MyBufferedReader(Reader reader){
this.reader=reader;
}
public String readLine() throws IOException{
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=reader.read())!=-1){
if(ch=='\r'){//空格則繼續
continue;
}else if(ch=='\n'){//每次返回一行
return sb.toString();
}else{
sb.append((char)ch);
}
}
return sb.toString();
}
public void close() throws IOException{
//緩沖對象的關(guān)閉方法其實(shí)就是調用流本身的close()
reader.close();
}
}
測試時(shí)把清單4的BufferedReader對象替換成MyBufferedReader對象即可。
清單6,測試mybufferedreader代碼
private static void test4(){
MyBufferedReader bufr=null;
BufferedWriter bufw=null;
try {
bufr=new MyBufferedReader(new FileReader("D:/a.txt"));
bufw=new BufferedWriter(new FileWriter("D:/b.txt"));
String line=null;
while((line=bufr.readLine())!=null){
bufw.write(line);//每次將一行寫(xiě)入緩沖區
bufw.flush();//刷新到目的地
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(bufw!=null){
bufw.close();
}
if(bufr!=null){
bufr.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
其實(shí)我們自己寫(xiě)的這個(gè)緩存對象就是對Reader對象進(jìn)行了功能的增強,Reader對象每次只能返回一個(gè)字符,而增強了功能之后該類(lèi)就可以每次返回一行字符,也就是設計模式中所說(shuō)的裝飾模式。
【java io流學(xué)習總結】相關(guān)文章:
java工作總結03-23
JAVA試用期工作總結02-20
java工程師工作總結04-10
java年終工作總結05-07
java程序員轉正工作總結05-10
Java實(shí)習報告范文03-22
JAVA轉正申請書(shū)02-02
JAVA工程求職信03-19
java個(gè)人年終工作總結05-19