2015/9/7 16:59:33
noBody 2015/9/7 16:59:33
https://office.inspur.com/eportal/ui?pageId=334521&fromUrl=aHR0cHM6Ly9vZmZpY2UuaW5zcHVyLmNvbS9lcG9ydGFsL3VpP3BhZ2VJZD0zMjk4ODQ=
6:25:54
noBody 2015/9/9 6:25:54
轉](轉自博客園)Java文件操做---文件讀取和寫入示例
2012-3-21閱讀3357 評論0
原文連接:
http://www.cnblogs.com/springcsc/archive/2009/12/03/1616367.html
雖然前面介紹了流的概念,可是這個概念對於初學者來講,仍是比較抽象的,下面以實際的讀取文件爲例子,介紹流的概念,以及輸入流的基本使用。
按照前面介紹的知識,將文件中的數據讀入程序,是將程序外部的數據傳入程序中,應該使用輸入流——InputStream或Reader。而因爲讀取的是特定的數據源——文件,則可使用輸入對應的子類FileInputStream或FileReader實現。
在實際書寫代碼時,須要首先熟悉讀取文件在程序中實現的過程。在Java語言的IO編程中,讀取文件是分兩個步驟:
一、將文件中的數據轉換爲流.
二、讀取流內部的數據.
其中第一個步驟由系統完成,只須要建立對應的流對象便可,對象建立完成之後步驟1就完成了,第二個步驟使用輸入流對象中的read方法便可實現了。
使用輸入流進行編程時,代碼通常分爲3個部分:
一、建立流對象.
二、讀取流對象內部的數據.
三、關閉流對象。
下面以讀取文件的代碼示例:
import java.io.*;
/**
* 使用FileInputStream讀取文件
*/
public class ReadFile1 {
public static void main(String[] args) {
//聲明流對象
FileInputStream fis = null;
try{
//建立流對象
fis = new FileInputStream("e:\\a.txt");
//讀取數據,並將讀取到的數據存儲到數組中
byte[] data = new byte[1024]; //數據存儲的數組
int i = 0; //當前下標
//讀取流中的第一個字節數據
int n = fis.read();
//依次讀取後續的數據
while(n != -1){ //未到達流的末尾
//將有效數據存儲到數組中
data[i] = (byte)n;
//下標增長
i++;
//讀取下一個字節的數據
n = fis.read();
}
//解析數據
String s = new String(data,0,i);
//輸出字符串
System.out.println(s);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
//關閉流,釋放資源
fis.close();
}catch(Exception e){}
}
}
}
在該示例代碼中,首先建立一個FileInputStream類型的對象fis:
fis = new FileInputStream("e:\\a.txt");
這樣創建了一個鏈接到數據源e:\a.txt的流,並將該數據源中的數據轉換爲流對象fis,之後程序讀取數據源中的數據,只須要從流對象fis中讀取便可。
讀取流fis中的數據,須要使用read方法,該方法是從InputStream類中繼承過來的方法,該方法的做用是每次讀取流中的一個字節,若是須要讀取流中的全部數據,須要使用循環讀取,當到達流的末尾時,read方法的返回值是-1。
在該示例中,首先讀取流中的第一個字節:
int n = fis.read();
並將讀取的值賦值給int值n,若是流fis爲空,則n的值是-1,不然n中的最後一個字節包含的時流fis中的第一個字節,該字節被讀取之後,將被從流fis中刪除。
而後循環讀取流中的其它數據,若是讀取到的數據不是-1,則將已經讀取到的數據n強制轉換爲byte,即取n中的有效數據——最後一個字節,並存儲到數組data中,而後調用流對象fis中的read方法繼續讀取流中的下一個字節的數據。一直這樣循環下去,直到讀取到的數據是-1,也就是讀取到流的末尾則循環結束。
這裏的數組長度是1024,因此要求流中的數據長度不能超過1024,因此該示例代碼在這裏具備必定的侷限性。若是流的數據個數比較多,則能夠將1024擴大到合適的個數便可。
通過上面的循環之後,就能夠將流中的數據依次存儲到data數組中,存儲到data數組中有效數據的個數是i個,即循環次數。
其實截至到這裏,IO操做中的讀取數據已經完成,而後再按照數據源中的數據格式,這裏是文件的格式,解析讀取出的byte數組便可。
該示例代碼中的解析,只是將從流對象中讀取到的有效的數據,也就是data數組中的前n個數據,轉換爲字符串,而後進行輸出。
在該示例代碼中,只是在catch語句中輸出異常的信息,便於代碼的調試,在實際的程序中,須要根據狀況進行必定的邏輯處理,例如給出提示信息等。
最後在finally語句塊中,關閉流對象fis,釋放流對象佔用的資源,關閉數據源,實現流操做的結束工做。
上面詳細介紹了讀取文件的過程,其實在實際讀取流數據時,還可使用其它的read方法,下面的示例代碼是使用另一個read方法實現讀取的代碼:
import java.io.FileInputStream;
/**
* 使用FileInputStream讀取文件
*/
public class ReadFile2 {
public static void main(String[] args) {
//聲明流對象
FileInputStream fis = null;
try{
//建立流對象
fis = new FileInputStream("e:\\a.txt");
//讀取數據,並將讀取到的數據存儲到數組中
byte[] data = new byte[1024]; //數據存儲的數組
int i = fis.read(data);
//解析數據
String s = new String(data,0,i);
//輸出字符串
System.out.println(s);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
//關閉流,釋放資源
fis.close();
}catch(Exception e){}
}
}
}
該示例代碼中,只使用一行代碼:
int i = fis.read(data);
就實現了將流對象fis中的數據讀取到字節數組data中。該行代碼的做用是將fis流中的數據讀取出來,並依次存儲到數組data中,返回值爲實際讀取的有效數據的個數。
使用該中方式在進行讀取時,能夠簡化讀取的代碼。
固然,在讀取文件時,也可使用Reader類的子類FileReader進行實現,在編寫代碼時,只須要將上面示例代碼中的byte數組替換成char數組便可。
使用FileReader讀取文件時,是按照char爲單位進行讀取的,因此更適合於文本文件的讀取,而對於二進制文件或自定義格式的文件來講,仍是使用FileInputStream進行讀取,方便對於讀取到的數據進行解析和操做。
讀取其它數據源的操做和讀取文件相似,最大的區別在於創建流對象時選擇的類不一樣,而流對象一旦創建,則基本的讀取方法是同樣,若是隻使用最基本的read方法進行讀取,則使用基本上是一致的。這也是IO類設計的初衷,使得對於流對象的操做保持一致,簡化IO類使用的難度。
程。
基本的輸出流包含OutputStream和Writer兩個,區別是OutputStream體系中的類(也就是OutputStream的子類)是按照字節寫入的,而Writer體系中的類(也就是Writer的子類)是按照字符寫入的。
使用輸出流進行編程的步驟是:
一、創建輸出流
創建對應的輸出流對象,也就是完成由流對象到外部數據源之間的轉換。
二、向流中寫入數據
將須要輸出的數據,調用對應的write方法寫入到流對象中。
三、關閉輸出流
在寫入完畢之後,調用流對象的close方法關閉輸出流,釋放資源。
在使用輸出流向外部輸出數據時,程序員只須要將數據寫入流對象便可,底層的API實現將流對象中的內容寫入外部數據源,這個寫入的過程對於程序員來講是透明的,不須要專門書寫代碼實現。
在向文件中輸出數據,也就是寫文件時,使用對應的文件輸出流,包括FileOutputStream和FileWriter兩個類,下面以FileOutputStream爲例子說明輸出流的使用。示例代碼以下:
import java.io.*;
/**
* 使用FileOutputStream寫文件示例
*/
public class WriteFile1 {
public static void main(String[] args) {
String s = "Java語言";
int n = 100;
//聲明流對象
FileOutputStream fos = null;
try{
//建立流對象
fos = new FileOutputStream("e:\\out.txt");
//轉換爲byte數組
byte[] b1 = s.getBytes();
//換行符
byte[] b2 = "\r\n".getBytes();
byte[] b3 = String.valueOf(n).getBytes();
//依次寫入文件
fos.write(b1);
fos.write(b2);
fos.write(b3);
} catch (Exception e) {
e.printStackTrace();
}finally{
try{
fos.close();
}catch(Exception e){}
}
}
}
該示例代碼寫入的文件使用記事本打開之後,內容爲:
Java語言
100
在該示例代碼中,演示了將一個字符串和一個int類型的值依次寫入到同一個文件中。在寫入文件時,首先建立了一個文件輸出流對象fos:
fos = new FileOutputStream("e:\\out.txt");
該對象建立之後,就實現了從流到外部數據源e:\out.txt的鏈接。說明:當外部文件不存在時,系統會自動建立該文件,可是若是文件路徑中包含未建立的目錄時將出現異常。這裏書寫的文件路徑能夠是絕對路徑也能夠是相對路徑。
在實際寫入文件時,有兩種寫入文件的方式:覆蓋和追加。其中「覆蓋」是指清除原文件的內容,寫入新的內容,默認採用該種形式寫文件,「追加」是指在已有文件 的末尾寫入內容,保留原來的文件內容,例如寫日誌文件時,通常採用追加。在實際使用時能夠根據須要採用適合的形式,可使用:
public FileOutputStream(String name, boolean append) throws FileNotFoundException
只須要使用該構造方法在構造FileOutputStream對象時,將第二個參數append的值設置爲true便可。
流對象建立完成之後,就可使用OutputStream中提供的wirte方法向流中依次寫入數據了。最基本的寫入方法只支持byte數組格式的數據,因此若是須要將內容寫入文件,則須要把對應的內容首先轉換爲byte數組。
這裏以以下格式寫入數據:首先寫入字符串s,使用String類的getBytes方法將該字符串轉換爲byte數組,而後寫入字符串「\r\n」,轉換方式同上,該字符串的做用是實現文本文件的換行顯示,最後寫入int數據n,首先將n轉換爲字符串,再轉換爲byte數組。這種寫入數據的順序以及轉換爲byte數組的方式就是流的數據格式,也就是該文件的格式。由於這裏寫的都是文本文件,因此寫入的內容以明文的形式顯示出來,也能夠根據本身須要存儲的數據設定特定的文件格式。
其實,全部的數據文件,包括圖片文件、聲音文件等等,都是以必定的數據格式存儲數據的,在保存該文件時,將須要保存的數據按照該文件的數據格式依次寫入便可,而在打開該文件時,將讀取到的數據按照該文件的格式解析成對應的邏輯便可。
最後,在數據寫入到流內部之後,若是須要當即將寫入流內部的數據強制輸出到外部的數據源,則可使用流對象的flush方法實現。若是不須要強制輸出,則只須要在寫入結束之後,關閉流對象便可。在關閉流對象時,系統首先將流中未輸出到數據源中的數據強制輸出,而後再釋放該流對象佔用的內存空間。
使用FileWriter寫入文件時,步驟和建立流對象的操做都和該示例代碼一致,只是在轉換數據時,須要將寫入的數據轉換爲char數組,對於字符串來講,可使用String中的toCharArray方法實現轉換,而後按照文件格式寫入數據便可。
對於其它類型的字節輸出流/字符輸出流來講,只是在邏輯上鍊接不一樣的數據源,在建立對象的代碼上會存在必定的不一樣,可是一旦流對象建立完成之後,基本的寫入方法都是write方法,也須要首先將須要寫入的數據按照必定的格式轉換爲對應的byte數組/char數組,而後依次寫入便可。
因此IO類的這種設計形式,只須要熟悉該體系中的某一個類的使用之後,就能夠舉一反三的學會其它相同類型的類的使用,從而簡化程序員的學習,使得使用時保持統一。
html