Java——IO總結1
對於任何程式設計語言而言,輸入輸出(Input/Output)系統都是非常核心的功能。程式執行需要資料,資料的獲取往往需要跟外部系統進行通訊,外部系統可能是檔案、資料庫、其他程式、網路、IO裝置等等。
輸入(Input)指的是:可以讓程式從外部系統獲得資料(核心含義是“讀”,讀取外部資料)。如:
讀取硬碟上的檔案內容到程式。例如:播放器開啟一個視訊檔案、word開啟一個doc檔案。
讀取網路上某個位置內容到程式。
讀取資料庫系統的資料到程式。
讀取某些硬體系統資料到程式。例如:車載電腦讀取雷達掃描資訊到程式;溫控系統等。
輸出(Output)指的是:程式輸出資料給外部系統從而可以操作外部系統(核心含義是“寫”,將資料寫出到外部系統)。常見的應用有:
將資料寫到硬碟中。例如:我們編輯完一個word文件後,將內容寫到硬碟上進行儲存。
將資料寫到資料庫系統中。例如:我們註冊一個網站會員,實際就是後臺程式向資料庫中寫入一條記錄。
將資料寫到某些硬體系統中。
流是一個抽象、動態的概念,是一連串連續動態的資料集合。
當程式需要讀取資料來源的資料時,就會通過IO流物件開啟一個通向資料來源的流,通過這個IO流物件的相關方法可以順序讀取資料來源中的資料。
一個簡單的流讀取資料:
public class Test1 { public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("d:/x.txt"); // 內容是:abc StringBuilder sb = new StringBuilder(); int temp = 0; //當temp等於-1時,表示已經到了檔案結尾,停止讀取 while ((temp = fis.read()) != -1) { sb.append((char) temp); } System.out.println(sb); } catch (Exception e) { e.printStackTrace(); } finally { try { //這種寫法,保證了即使遇到異常情況,也會關閉流物件。 if (fis != null) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
IO流總結:
1. 按流的方向分類:
輸入流:資料來源到程式(InputStream、Reader讀進來)。
輸出流:程式到目的地(OutPutStream、Writer寫出去)。
2. 按流的處理資料單元分類:
位元組流:按照位元組讀取資料(InputStream、OutputStream),命名上以Stream結尾的流一般是位元組流,如FileInputStream、FileOutputStream。
字元流:按照字元讀取資料(Reader、Writer),命名上以Reader/Writer結尾的流一般是字元流,如FileReader、FileWriter。
3. 按流的功能分類:
節點流:可以直接從資料來源或目的地讀寫資料,如FileInputStream、FileReader、DataInputStream等。
處理流:不直接連線到資料來源或目的地,是”處理流的流”。通過對其他流的處理提高程式的效能,如BufferedInputStream、BufferedReader等。處理流也叫包裝流。
4. IO的四個基本抽象類:InputStream、OutputStream、Reader、Writer
5. InputStream的實現類:
FileInputStream
ByteArrayInutStream
BufferedInputStream
DataInputStream
ObjectInputStream
6. OutputStream的實現類:
FileOutputStream
ByteArrayOutputStream
BufferedOutputStream
DataOutputStream
ObjectOutputStream
PrintStream
7. Reader的實現類
FileReader
BufferedReader
InputStreamReader
8. Writer的實現類
FileWriter
BufferedWriter
OutputStreamWriter
9. 把Java物件轉換為位元組序列的過程稱為物件的序列化。
10. 把位元組序列恢復為Java物件的過程稱為物件的反序列化。
示例
利用檔案位元組流(FileInputStream/FileOutputStream)實現檔案的複製
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestFileCopy { public static void main(String[] args) { //將a.txt內容拷貝到b.txt copyFile("d:/a.txt", "d:/b.txt"); } /** * 將src檔案的內容拷貝到dec檔案 * @param src 原始檔 * @param dec 目標檔案 */ static void copyFile(String src, String dec) { FileInputStream fis = null; FileOutputStream fos = null; //為了提高效率,設定快取陣列!(讀取的位元組資料會暫存放到該位元組陣列中) byte[] buffer = new byte[1024]; int temp = 0; try { fis = new FileInputStream(src); fos = new FileOutputStream(dec); //邊讀邊寫 //temp指的是本次讀取的真實長度,temp等於-1時表示讀取結束 while ((temp = fis.read(buffer)) != -1) { /*將快取陣列中的資料寫入檔案中,注意:寫入的是讀取的真實長度; *如果使用fos.write(buffer)方法,那麼寫入的長度將會是1024,即快取 *陣列的長度*/ fos.write(buffer, 0, temp); } } catch (Exception e) { e.printStackTrace(); } finally { //兩個流需要分別關閉 try { if (fos != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (fis != null) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
使用檔案字元流FileReader與FileWriter實現文字檔案的複製
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class TestFileCopy2 { public static void main(String[] args) { // 寫法和使用Stream基本一樣。只不過,讀取時是讀取的字元。 FileReader fr = null; FileWriter fw = null; int len = 0; try { fr = new FileReader("d:/a.txt"); fw = new FileWriter("d:/d.txt"); //為了提高效率,建立緩衝用的字元陣列 char[] buffer = new char[1024]; //邊讀邊寫 while ((len = fr.read(buffer)) != -1) { fw.write(buffer, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fw != null) { fw.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (fr != null) { fr.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
使用緩衝位元組流BufferedInputStream和BufferedOutputStream實現檔案的高效率複製
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestBufferedFileCopy1 { public static void main(String[] args) { copyFile1("D:/電影/華語/大陸/尚學堂傳奇.mp4", "D:/電影/華語/大陸/尚學堂越 "+"來越傳奇.mp4"); } /**緩衝位元組流實現的檔案複製的方法*/ static void copyFile1(String src, String dec) { FileInputStream fis = null; BufferedInputStream bis = null; FileOutputStream fos = null; BufferedOutputStream bos = null; int temp = 0; try { fis = new FileInputStream(src); fos = new FileOutputStream(dec); //使用緩衝位元組流包裝檔案位元組流,增加緩衝功能,提高效率 //快取區的大小(快取陣列的長度)預設是8192,也可以自己指定大小 bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); while ((temp = bis.read()) != -1) { bos.write(temp); } } catch (Exception e) { e.printStackTrace(); } finally { //注意:增加處理流後,注意流的關閉順序!“後開的先關閉!” try { if (bos != null) { bos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (bis != null) { bis.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (fos != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (fis != null) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
使用緩衝字元流BufferedReader與BufferedWriter實現文字檔案的複製
BufferedReader/BufferedWriter增加了快取機制,大大提高了讀寫文字檔案的效率,同時,提供了更方便的按行讀取的方法:readLine(); 處理文字時,我們一般可以使用緩衝字元流。
1. readLine()方法是BufferedReader特有的方法,可以對文字檔案進行更加方便的讀取操作。
2. 寫入一行後要記得使用newLine()方法換行。
public class TestBufferedFileCopy2 { public static void main(String[] args) { // 注:處理文字檔案時,實際開發中可以用如下寫法,簡單高效!! FileReader fr = null; FileWriter fw = null; BufferedReader br = null; BufferedWriter bw = null; String tempString = ""; try { fr = new FileReader("d:/a.txt"); fw = new FileWriter("d:/d.txt"); //使用緩衝字元流進行包裝 br = new BufferedReader(fr); bw = new BufferedWriter(fw); //BufferedReader提供了更方便的readLine()方法,直接按行讀取文字 //br.readLine()方法的返回值是一個字串物件,即文字中的一行內容 while ((tempString = br.readLine()) != null) { //將讀取的一行字串寫入檔案中 bw.write(tempString); //下次寫入之前先換行,否則會在上一行後邊繼續追加,而不是另起一行 bw.newLine(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (bw != null) { bw.close(); } } catch (IOException e1) { e1.printStackTrace(); } try { if (br != null) { br.close(); } } catch (IOException e1) { e1.printStackTrace(); } try { if (fw != null) { fw.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (fr != null) { fr.close(); } } catch (IOException e) { e.printStackTrace(); } } } }