java I/O流詳解
概況
I/O流主要分為二大類別:字符流和字節流。
字節流(基本流)
1、字節輸入流 類名:FileInputStream 特點:讀(對文件進行讀取操作) 父類:InputStream
2、字節輸出流 類名:FileOutputStream 特點:寫 (對文件進行寫入操作) 父類:OutputStream
字符流(基本流)
1、字符輸入流 類名:FileReader 特點:讀(對文件進行讀取操作) 父類:InputStreamReader
2、字符輸出流 類名:FileWriter 特點:寫 (對文件進行寫入操作) 父類:OutputStreamWriter
緩沖流
字節緩沖流
1、緩沖字節輸入流 類名:BufferedInputStream 特點:讀(對文件進行讀取操作) 父類:FilterInputStream
2、緩沖字節輸出流 類名:BufferedOutputStream 特點:寫 (對文件進行寫入操作) 父類:FilterOutputStream
字符緩沖流
1、緩沖字符輸入流 類名:BufferedReader 特點:讀(對文件進行讀取操作) 父類:Reader (基本輸入流多了readLine()
一次讀取一行方法)
2、緩沖字符輸出流 類名:BufferedWriter 特點:寫 (對文件進行寫入操作) 父類:Writer (比基本輸出流多了newLine
換行方法)
轉換流
1、InputStreamReader 特點:讀 (對文件進行讀取操作) 輸入流 父類:Reader
2、OutputStreamWriter 特點:寫 (對文件進行寫入操作) 輸出流 父類:Writer
打印流
1、PrintStream 特點:寫 (對文件進行寫入操作) 底層:基本字節流
2、PrintWriter 特點:寫 (對文件進行寫入操作) 底層:基本字符流
基本字節流和基本字符流的區別:
1、字節流可以讀寫任何文件 字符流只能讀取普通文件
2、讀寫文本文件盡量使用字符流 這要比字節流效率高
3、讀寫媒體文件用字節流
4、基本字節流沒有緩沖區
5、基本字符流有緩沖區 默認大小為8k (不能指定緩沖區大小)
6、字節流是一個一個字節讀 效率比較低 雖然可以讀取各種各樣的文件但是 最適用於讀取媒體文件
7、字符流是一個一個字符讀 效率比較高
緩沖流和基本流的區別:
1、緩沖流效率要高於基本流
2、緩沖字符流彌補了基本字符流不能設置緩沖區大小的缺口
3、緩沖字節流和基本字節流相比 建議使用基本字節流
4、緩沖字符流和基本字符流相比 建議使用緩沖字符流
轉換流的作用
轉換流的作用主要是解決在進行讀寫操作時出現的中文亂碼 (java默認處理文件時是gbk 當將文本文件保存為utf-8的時候 進行讀寫操作就會出現中文亂碼)
// 用轉換流讀寫 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"), "utf-8"); osw.write("中國"); osw.close(); InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"utf-8"); char[] cc = new char[10]; isr.read(cc); String ss = new String(cc); System.out.println(ss); isr.close();
API圖
用法總結:
1、多媒體類 用字節流
讀:基本字節輸入流
寫:基本字節輸出流
2、文件文件 用字符流
讀:建議用字符緩沖輸入流
寫:建議用字符緩沖輸出流 如果寫的數據多種多樣的建議用打印流(PrintStream、PrintWriter)
3、比較明顯意圖的數據流
讀寫對象只能用對象流(ObjectInputStream、ObjectOutputStream)
如果在讀寫文件的過程中遇到中文亂碼只能用轉換流(InputStreamReader、OutputStreamWriter)
簡單實例:
復制較小文件代碼:
// 復制較小文件 // 先讀後寫 讀的時候文件必須存在 不會自動創建 寫的時候文件可以不存在會自動創建 File f = new File("D:\\practice\\backend\\a.txt"); FileInputStream fis = new FileInputStream(f); byte[] b = new byte[(int)f.length()]; fis.read(b); fis.close(); // 寫 FileOutputStream fos = new FileOutputStream("D:\\practice\\backend\\b.txt");//不存在會自動創建 fos.write(b); fos.close();
復制較大文件代碼:
// 讀取復制大文件 // 一邊讀一邊寫 FileInputStream fis = new FileInputStream("D:\\practice\\backend\\hello.mp4");//不存在不會自動創建 FileOutputStream fos = new FileOutputStream("D:\\practice\\backend\\h.mp4");//不存在會自動創建 byte[] b = new byte[1024*1024];//每次讀取1M while(true){ int len = fis.read(b); System.out.println(len); if(len == -1){ break;//當返回值是-1 證明文件已經讀取完 終止循環 } fos.write(b, 0, len); } fis.close(); fos.close();
利用遞歸查找某個目錄下的視頻文件
public class Demo7 { public static void findAvi(String pathName){ File ff = new File(pathName); File[] fss = ff.listFiles(); for (File fa : fss) { if(fa.isFile()){//判斷是否是文件 if(fa.getName().endsWith(".mp4")){//判斷是否是視頻文件 System.out.println(fa); } }else{ findAvi(fa.getPath()); } } } public static void main(String[] args) { // 遞歸查找某個目錄下的視頻文件 // E:\迅雷下載 String ss = "E:\\迅雷下載"; findAvi(ss);//靜態方法只能訪問靜態方法 } }
java I/O流詳解