輸入:將檔案內容由磁碟機讀入後暫存到記憶體內
輸出:將記憶體內暫存資料寫入到檔案中或者將訊息顯示在螢幕上
在java裡面,資料的輸出與輸入皆以串流(stream)的概念進行。串流的資料是由chracters與bit組成。
在處理IO時候要說清楚資料的來源(source)與目的地(sink)
注意stream型態
分成byte stream以及 character stream
byte stream以1byte為單位(位元為主)傳輸資料,長相InputStream/OutputStream;
除了可用於文字檔輸出入之外
也可用於非文字檔(二進位檔案binary file)、圖形檔的輸入輸出
character stream以字元為單位傳輸資料,長相reader/writer
用於文字檔的輸出輸入,避免產生亂碼。
which:
以下IO類別皆放在java.io類別庫之下。
架構如下:
java.io套件:
一、File //管理目錄底下的檔案與目錄。
二、InputStream//以byte為單位輸入
1.FileInputStream//讀取檔案可讀文字檔也可讀圖檔
2.ObjectInputStream
三、OutputStream//以byte為單位輸出
1.FileOutputStream//輸出成檔案
2.ObjectOutputStream
四、Reader//以字元為單位輸入
1.InputStreamReader
a.FileReader
2.BufferedReader
五、Writer//以字元為單位輸出
1.OutputStreamWriter
a.FileWriter
2.BufferedWriter
一、File
查詢檔名、size、修改日期。
不可存取檔案內容。資料夾也是一種檔案。
File file1 = new File("路徑");
File file2 = new File(File 變數或String 路徑,String 檔案名稱);
list():列出資料夾內的檔名
delete():刪除檔案,如果資料夾內有檔案,必須先刪除
二、InputStream/OutputStream
1.FileInputStream/FileOutputStreamFileInputStream fis = new FileInputStream("路徑+檔名");
fis.read():以1byte為單位讀取的檔案內容,回傳整數值。
如果沒有讀到任何字元則會回傳-1。
FileOutputStream fos = new FileOutputStream("路徑檔名");
fos.write(int變數或byte陣列);//將檔案內容寫入fos
fos.close();//關閉檔案,如果不關閉會留在記憶體之中
tip:
1.
輸出到文字檔案以附加方式輸出
FileOutputStream fos = new FileOutputStream("路徑檔名",true);
不過用這樣方式輸出圖檔無法以附加方式輸出
2.
int available();//傳回所讀的檔案bytes大小。
這個method是FileInputStream僅有的
可以寫出檔案時事先知道檔案的大小。
FileInputStream fi=new FileInputStream("D:/java/train.txt");//讀取檔案來源
System.out.println("file size"+fi.available());//取得檔案大小
byte ba[]=new byte[fi.available()];//宣告符合檔案大小的byte陣列
fi.read(ba);//將檔案內容讀到ba
System.out.println(new String(ba));//轉成字串,列印
fi.close();
BufferedInputStream/BufferedOutputStream
在記憶體設立緩衝區,批次處理檔案的輸出與輸入,如此一來減少硬碟的讀取次數。用法:BufferedInputStream bis = new BufferedInputStream(InputStream類別變數或者new InpuStream("路徑檔名"));
FileReader/FileWriter
用法與FileInputStream一樣英文的文字檔傳輸沒有問題,ANSI檔案的中文字會發生亂碼,UTF8才可以正常輸出,傳輸圖檔會開不起來。
char data[] = new char[128];
FileReader fr = new
FileReader("D:\\java\\train.txt");
int num=fr.read(data); //將檔案傳入自原陣列,回傳讀的字元數目。
//ANSI的中文字視為兩個字元(我這個字是為一個字元,UTF8檔案中文視為一個字元)
System.out.println(num);//列印檔案讀去的字元數
System.out.println("-------------------------");
System.out.println(data);//列印陣列的內容
String str = new String(data,0,num);
//String(char[],起始點,轉換長度);
System.out.println(str);
//轉換字串後列印結果跟轉換前是一樣的
}
}
BufferedReader/BufferedWriter
用法跟BufferedInputStream一樣BufferedReader除了read()方法之外也可以用
readLine()從檔案抓取文字,一次抓取一行,readLine回傳字串值。
將檔案輸出到新的文字檔並不會自動換行
要用BufferedWriter的方法newLine()才會換行
PrintWriter
官方文件說這是格式化輸出。目前不知道何謂格式化輸出?句法跟BufferedWrtier一樣,照樣造句
PrintWriter bw1=new PrintWriter(new FileWriter(路徑));
用bw1.println(String變數)
輸出文字到檔案,會自動換行
DataInputStream/DataOutputStream
ObjectInputStream/ObjectOutputStream
以物件型式讀入、讀出資料。原本資料是物件(ex:在程式碼裡面宣告類別建立物件),以文字型式將資料寫入檔案內,之後取出來便無法以物件方式取出。所以無法直接取得類別的屬性值。
要使用ObjectOutputStream類別將物件寫入檔案,該物件必須是可序列化(serializable)物件。該物件以及該物件內所屬的類別必須實作Serializable介面。否則會產生NotSerializableException事件。
ObjectInputStream則是用反序列化將物件從檔案讀取。
序列化:將物件內所有的屬性以及相關資料依照一定的順序轉成byte型式後寫入檔案。
如果有屬性不想被序列化那麼要在屬性前面加上transient或者static修飾詞。
(將資料輸出檔案用文字編輯器開啟是亂碼,看起來前面部分是描述物件的schema,後面部分是描述個物件的屬性值)
應用:檔案存取、網路資料傳送、影像檔案傳送
範例:
class book implements Serializable{//即將被序列化所以要實作Serializable
String name;//這個name也是物件,類別庫裡面已經實作介面所以我們不用再對他實作
double price;//同上
String author;//同上
public book(String name,double price,String author){
this.name=name;
this.price=price;
this.author=author;
}
public void show(){
System.out.println("書名"+name);
System.out.println("定價"+price);
System.out.println("作者"+author);
}}
File file = new File("D:/temp/kaiba.txt");//隨便準備一個檔案,作為輸出檔案
book[] books = new book[2];//宣告類別陣列
books[0]=new book("Conan",100.0,"formosa");
books[1]=new book("Doraemon",99.9,"FFFF");
FileOutputStream fos = new FileOutputStream(file);//將檔案(file)與OutputStream串接
ObjectOutputStream oos = new ObjectOutputStream(fos);//串接
for(Object book:books)//foreach
oos.writeObject(book);//將物件寫入outputstream,而且被轉換成Object類型
oos.close();
fos.close();
//-------------------以下讀取檔案--------------------//
FileInputStream fis= new FileInputStream(file);//將剛剛的檔案與inputStream串接
ObjectInputStream ois = new ObjectInputStream(fis);//串接
System.out.println(file.getName()+"檔案內容如下");
System.out.println("-----------------");
try{
while(true){
((book)ois.readObject()).show();
//讀取物件並轉換成book(因為讀出的是object物件),並呼叫show method
}
}catch(Exception e){
//處理例外,讀到沒有物件時會拋出例外,所以用try catch
}
ois.close();
fis.close();
}
InputStreamReader/OutputStreamWirter
InputStreamReader是byte轉成字元的橋樑。讀取byte轉成字元。OutputStreamWriter是字元轉成byte的橋樑
轉成什樣字元端看平台的字元預設值。用netbean執行打中文出現亂碼。
因為平台字元預設為utf8處理字元,
我們可以用System.out.println(OSWout.getEncoding());
得知目前用什麼編碼處理字串。
如果處理中文字的話,要加上"big5"指定編碼
InputStreamReader ISRkeyin = new InputStreamReader(InputStream,"big5");
OutputStreamWriter OSWout = new OutputStreamWriter(OutputStream,"big5");
以上兩個缺一不可。
how:
基本操作SOP如下:
1. 指定資料源頭(source)
InputStream keyin = System.in;//源頭來自於使用者鍵盤輸入
InputStreamReader ISRkeyin = new InputStreamReader(keyin,"big5");//byte轉字元。因為System.in是InputStream以byte為單位處理。要丟入以字元為單位處了的buffer所以要轉換。
BufferedReader input = new BufferedReader(ISRkeyin);//字元
2.指定輸出目的地sink
FileOutputStream file = new FileOutputStream("D:/temp/ooxx.txt");//byte完單位
OutputStreamWriter OSWout = new OutputStreamWriter(file,"big5");//字元轉byte
BufferedWriter output = new BufferedWriter(OSWout);
3.
//System.out.println(ISRkeyin.getEncoding());
//System.out.println(OSWout.getEncoding());
String str;
while(( str=input.readLine())!=null) //程式執行到這裡會讓使用者輸入文字,我在這邊又在while這行多打上了分號,結果沒執行下方的程式。
{
if(str.equalsIgnoreCase("Q"))//忽略大小寫,檢查輸入字串
{
input.close();
output.close();
System.exit(-1);//告訴系統結束執行程式。否則仍會繼續執行while,然後拋出例外,也可以打上return ; 也有同樣效果
}
output.write(str);
//OSWout.write(str);//不用buffer也可以將文字輸出到檔案
output.newLine();
System.out.println("你剛才打的文字是:"+str);
}
4.關閉stream
input.close();
output.close();
}
PS:若省略BufferedReader、BufferedWriter就無法直接讀取輸入String型態的串流\
BufferedReader沒有readLine()
沒有留言:
張貼留言