更新時間:2020-06-01 16:15:13 來源:動力節點 瀏覽2276次
所謂的IO即Input(輸入)/Output(輸出),當軟件與外部資源(例如:網絡,數據庫,磁盤文件)交互的時候,就會用到IO操作。而在IO操作中,最常用的一種方式就是流,也被稱為IO流。IO操作比較復雜,涉及到的系統調用比較多,相對操作內存而言性能很低。然而值得興奮的是,Java提供了很多實現類以滿足不同的使用場景,這樣的實現類有很多,我只挑選些在日常編碼中經常用到的類進行說明,本節主要介紹和文件操作相關的流,下面一起來瞧瞧吧。
FileOutputStream&FileInputStream字節流
File只是能操作文件或文件夾,但是并不能操作文件中的內容,要想操作文件的內容就需要使用文件IO流,其操作文件的內容主要有兩種方式:以字節的方式和以字符的方式。而該小節主要講以字節文件流的形式操作文件內容,以字符文件流的方式操作我留到下一小節進行說明。
在Java中以字節流的形式操作文件內容的類主要是FileOutputStream和FileInputStream。分別是OutputStream(字節輸出流)和InputStream(字節輸入流)抽象基類的子類。下面以圖片的復制來展示下該流的用法。
File?sourceFile?=?new?File("sourceFile.jpg");?
File?destFile?=?new?File("destFile.jpg");
FileInputStream?fis=null;?//?讀取源文件的流
FileOutputStream?fos?=?null;?//?輸出到目標文件的流
try?{
?fis?=?new?FileInputStream(sourceFile);
?fos?=?new?FileOutputStream(destFile);
?byte[]?bytes=?new?byte[1024];
?int?len?=?0;
?while((len=fis.read(bytes))!=-1)?{
?fos.write(bytes,?0,?len);
?}
}
catch(IOException?ex)?{}
finally?{
?try?{?fis.close();}?catch(IOException?ex)?{}?
?try?{?fos.close();}?catch(IOException?ex)?{}?
}
在使用FileOutputStream和FileInputStream的過程中需要注意的地方:
FileInputStream所要操作的文件必須存在,否則就會拋出異常。而FileOutputStream寫入的目的文件則不需要存在,當不存在時會被創建,存在的時候會被覆蓋,也可以使用FileOutputStream造函數的第二個參數,來實現追加文件內容。
在使用FileInputStream讀取字節的時候,當讀取到字節的末尾,再繼續讀取,無論多少次都會返回-1,而返回值len表示本次讀取了多少個字節。通常情況下每次讀取1024個字節,可以達到空間和時間的平衡。但是具體情況也是需要具體分析的。
字節流是不存在緩沖區的,所以不需要使用flush操作刷新緩沖區,字節的讀取和寫入都是通過操作系統來實現的。
只要是流就是需要關閉的,無論是否在異常情況下都需要關閉流,防止占用系統資源,導致其他程序無法對該文件進行操作。但是在關閉流的時候也有可能會報異常,所以也需要try...catch。
FileOutputStream和FileInputStream主要用來操作字節表現形式的文件,例如圖片,可執行程序等。當然操作字符表現形式的文件也是沒有問題的,只不過這么干不規范。
OutputStreamWriter&InputStreamReader
這小節主要講以字符流的形式操作文件,在Java中對應操作的主要類為OutputStreamWriter和InputStreamReader。有時候又稱它們為轉換流,具體原因一會在說,先看一個例子。
File?sourceFile?=?new?File("sourceFile.txt");
File?destFile?=?new?File("destFile.txt");
?
FileInputStream?fis=?new?FileInputStream(sourceFile);
FileOutputStream?fos?=?new?FileOutputStream(destFile);?
InputStreamReader?reader=null;
OutputStreamWriter?writer=null;
try?{
?reader=?new?InputStreamReader(fis,"utf-8");
?writer?=new?OutputStreamWriter(fos,"gbk");
?char[]?cbuf?=new?char[1024];
?int?len=0;
?while((len=reader.read(cbuf))!=-1)?{
?System.out.println(String.copyValueOf(cbuf,0,len));
?writer.write(cbuf,?0,?len);
?}
}
catch(IOException?ex)?{
?try{reader.close();}catch(IOException?ex)?{?}
?try{writer.close();}catch(IOException?ex)?{?}
}
上述示例主要實現了一個文件的復制,與字節流的使用方式不同的是,字符流的構造函數需要傳遞字節流和編碼格式。這是因為操作文件內容都是以字節的形式來操作的。字符輸入流根據編碼表對字節流讀取的字節轉義成字符,同時也說明了傳遞編碼表格式參數的重要性。如果被讀取文件編碼格式是UTF-8且不傳遞這個參數,那么這個參數為操作系統的默認編碼表(對于Windows而言是GBK),如果默認的編碼表與UTF-8不同(與系統編碼表格式相同,可不傳遞此參數),在轉義為字符的過程中就會出現問題。假如文件內容為“好”,在UTF-8中對應的字節為-10-20-30。那么就以系統的默認編碼表來轉義,假如默認為GBK,“好”字的編碼為-50-60,由原來3個字節表示漢字,現在變成了2個字節表示漢字,又由于編碼表不兼容,所以導致出現亂碼。而在使用字符輸出流的時候,將字符按照編碼表參數轉化為字節后再寫入對應編碼格式的文件中去。如果輸出的內容是以追加的方式,那么需要保證前后兩個輸出文件內容的編碼格式一樣,否則也會出現亂碼。假如之前的輸出文件是GBK格式,你使用字符輸出流輸出的字符格式為UTF8并追加到文件中去,這個時候亂碼就產生了。綜上過程,也就知道大家為什么又稱FileOutputStream和InputStreamReader為轉換流了。
傳遞給字符流的字節流不需要單獨的進行關系,在字符流關閉的時候會調用字節流的close()方法。
以上就是動力節點java培訓機構的小編針對“Java常用io文件流的基本使用”的內容進行的回答,希望對大家有所幫助,如有疑問,請在線咨詢,有專業老師隨時為你服務。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習