對於任何程序設計語言而言,輸入輸出(Input/Output)系統都是很是核心的功能。程序運行須要數據,數據的獲取每每須要跟外部系統進行通訊,外部系統多是文件、數據庫、其餘程序、網絡、IO設備等等。java
輸入(Input)指的是:可讓程序從外部系統得到數據(核心含義是「讀」,讀取外部數據)。如:數據庫
讀取硬盤上的文件內容到程序。例如:播放器打開一個視頻文件、word打開一個doc文件。數組
讀取網絡上某個位置內容到程序。緩存
讀取數據庫系統的數據到程序。網絡
讀取某些硬件系統數據到程序。例如:車載電腦讀取雷達掃描信息到程序;溫控系統等。app
輸出(Output)指的是:程序輸出數據給外部系統從而能夠操做外部系統(核心含義是「寫」,將數據寫出到外部系統)。常見的應用有:ide
將數據寫到硬盤中。例如:咱們編輯完一個word文檔後,將內容寫到硬盤上進行保存。性能
將數據寫到數據庫系統中。例如:咱們註冊一個網站會員,實際就是後臺程序向數據庫中寫入一條記錄。網站
將數據寫到某些硬件系統中。ui
流是一個抽象、動態的概念,是一連串連續動態的數據集合。
當程序須要讀取數據源的數據時,就會經過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(); } } } }