IO流:數據傳輸是需要通道的,而IO流就是數據傳輸的通道。
IO流可以形象的比喻為運送貨物的傳輸帶。
IO流的分類:
①根據操作的數據類型的不同可以分為 :字節流與字符流。
②根據數據的流向分為:輸入流與輸出流,程序(內存)作為參照物,程序從外部讀取稱為輸入(Input),程序向外部寫數據成為輸出(Output)。
字節輸入流:
父類:InputStream
常用的字節輸入流:FileInputStream
1.FileInputStream
①構造方法:
FileInputStream(File)
FileInputStream(String filename)
2.常用方法
①read :讀取一個字節,返回該字節的值,如果到達文件的末尾,則返回-1。需要注意:read()方法和迭代器一樣,會自動下移的
②read(byte[ ])從輸入流中讀取至多一個數組長度的內容,到達文件末尾,則返回-1。
- 數組稱為緩沖區數組,大小一般取值為1024的整數倍。
- 轉換為字符時,使用String(byte [ ] bytes,int offset,int length)
- available()沒有讀取的剩余字節數,如果該文件還從未被讀取,就返回該文件的長度。
- close() 關閉流並釋放資源
字節輸入流代碼演示:
其中1.txt位於本項目的根目錄下:內容為"abcdefg"
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.IOException; 4 5 public class Demo6 { 6 7 public static void main(String[] args) throws IOException{ 8 File file=new File("1.txt"); //新建一個文件的抽象路徑 9 FileInputStream fis=new FileInputStream(file); 10 int result=fis.read(); 11 System.out.println(result); 12 13 } 14 15 }
程序執行的結果為97,因為讀取的a的ASCII碼值

字節輸入流的循環讀取:
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.IOException; 4 5 public class Demo7 { 6 7 public static void main(String[] args) throws IOException{ 8 File file =new File("1.txt"); 9 FileInputStream fis=new FileInputStream(file); 10 int result; 11 while((result=fis.read())!=-1) { 12 System.out.print(result+"\t"); 13 } 14 15 16 } 17 18 }
打印了a到g的ASCII碼值

字符流的讀取方法:
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.IOException; 4 5 public class Demo8 { 6 7 public static void main(String[] args) throws IOException{ 8 File file =new File("1.txt"); 9 FileInputStream fis=new FileInputStream(file); 10 byte[] bt=new byte[1024]; 11 int count; 12 while((count=fis.read(bt))!=-1) { 13 String string =new String(bt,0,count); 14 System.out.println(string); 15 } 16 } 17 }
輸出結果

下面可以用同樣的文件來比較字節輸入流和字符輸入流的讀取速度:
文件是一張格式為png圖片
先是字節輸入流的讀取速度
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.IOException; 4 5 public class Demo9 { 6 7 public static void main(String[] args) throws IOException{ 8 File file =new File("D:\\Java代碼\\123.png"); 9 FileInputStream fis=new FileInputStream(file); 10 int count; 11 long start=System.currentTimeMillis(); 12 while((count=fis.read())!=-1) { 13 System.out.println(count); 14 } 15 long end=System.currentTimeMillis(); 16 System.out.println("======下面是所用的時間======"); 17 System.out.println(end-start); 18 } 19 20 }
結果如下:

下面是字符輸入流:
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.IOException; 4 5 public class Demo10 { 6 7 public static void main(String[] args) throws IOException { 8 File file=new File("D:\\Java代碼\\123.png"); 9 FileInputStream fis=new FileInputStream(file); 10 byte[] bt=new byte[1024]; 11 int count; 12 long start=System.currentTimeMillis(); 13 while((count=fis.read(bt))!=-1) { 14 System.out.println(count); 15 } 16 long end=System.currentTimeMillis(); 17 System.out.println("======下面是所用的時間======"); 18 System.out.println(end-start); 19 } 20 }
結果如下:

字節輸入流讀取文件花費了760毫秒,而字符輸入流讀取文件花費了3毫秒,由此可見,字符輸入流的速度要比字節輸入流更快。
文件字節輸出流:
字節輸出流:OutputStream 是所有輸出流的超類
常用子類:FileOutputStream 文件字節輸出流
構造方法:
FileOutputStream(File file) /FileOutputStream(String name)
注意:如果父目錄不存在,會報FileNotFoundException異常,如果父目錄存在,會創建一個新的文件,如果此時已經有文件存在,會覆蓋原文件
FileOutputStream(File file,boolean flag)/FileOutputStream(String name,boolean flag)
注意:如果當前文件需要從文件末尾進行插入(接着文件里的內容繼續寫),必須將第二個參數設置為true,默認不寫為false,會覆蓋原文件
常用方法:
write(int)向文件中寫入一個字節的值
write(byte[]) 向文件中寫入一個數組的數據。
***③ write(byte[] offset len) 將 偏移量為 offset 的索引位置的長度為 len 的數據,寫入到輸出流中。
代碼示例:
1 import java.io.File; 2 import java.io.FileOutputStream; 3 import java.io.IOException; 4 5 public class Demo11 { 6 7 public static void main(String[] args) throws IOException { 8 File file=new File("3.txt"); 9 FileOutputStream fos=new FileOutputStream(file); 10 11 fos.write("沒有絕對的絕緣體,只有不努力的電壓。".getBytes()); 12 } 13 }
執行結果,會在本項目的根目錄下生成一個3.txt 文件,並且將內容寫入進去。

文件復制:將一個文件通過IO流復制到另一個文件中去
代碼示例:
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 6 public class Demo12 { 7 8 public static void main(String[] args) throws IOException { 9 File file=new File("1.txt"); 10 FileInputStream fis=new FileInputStream(file); 11 FileOutputStream fos=new FileOutputStream(new File("4.txt")); 12 byte[] bt=new byte[1024]; 13 int count; 14 while((count=fis.read(bt))!=-1) { 15 fos.write(bt,0,count); 16 } 17 fis.close(); 18 fos.close(); 19 } 20 }
結果會將1.txt的內容復制到4.txt中

帶緩沖區的字節流
1. 通過比較 read() 與 read(byte[]) 的方法復制文件的時間的長短,可以看出,帶緩沖區的讀寫文件的速度快,
java 上提供了專門帶緩沖區的字節流,用以提高讀寫速度。
2.BufferedInputStream /BufferedOutputStream 帶緩沖區的字節輸入 / 輸出流
3. 結論: 帶緩沖區的字節流 讀取速度高於字節流
代碼演示:
1 public class 帶緩沖區的字節流 { 2 public static void main(String[] args) throws IOException { 3 /*FileInputStream fis=new FileInputStream(new File("src\\com\\ 文件復制 .java")); 4 // 復制操作 : 5 BufferedInputStream bis=new BufferedInputStream(fis);*/ 6 // // 讀取 7 // BufferedInputStream bis=new BufferedInputStream(new FileInputStream(new File("src\\com\\ 文 8 件復制 .java"))); 9 // // 寫入 10 // BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(new File("1.java")) 11 ); 12 // 讀取 13 BufferedInputStream bis=new BufferedInputStream(new FileInputStream(new File("D:\\0318java 班 14 \\day08\\ 錄屏 \\1_day08IO 流概述 .mp4"))); 15 // 寫入 16 BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(new File("C:\\Users\\ 17 Administrator\\Desktop\\2.mp4"))); 18 byte[] bt=new byte[1024]; 19 int count=0; 20 long start=System.currentTimeMillis(); 21 while((count=bis.read(bt))!=-1) { 22 bos.write(bt, 0, count); 23 } 24 long end=System.currentTimeMillis(); 25 System.out.println(end-start); 26 bis.close(); 27 bos.close(); 28 } 29 }
jdk1.6 流的異常處理
1. 異常處理方式:
① try-catch-finally 異常的捕獲
② throws 異常的聲明
2. 以文件復制的形式來寫流的異常處理 :
在 1.7jdk 之前包括 1.6 不包含 1.7 的流的異常處理形式。
代碼演示:
1 public class 字節流的異常處理方式 { 2 public static void main(String[] args) { 3 // 為了在 finally 里面能夠使用關閉資源,提升作用域 4 FileInputStream fis=null; 5 FileOutputStream fos=null; 6 try { 7 // 輸入流 8 fis=new FileInputStream(new File("src\\com\\ 帶緩沖區的字節流 .java")); 9 // 輸出流 10 fos=new FileOutputStream(new File("2.java")); 11 // 文件復制 12 byte[] bt=new byte[1024]; 13 int count=0; 14 while((count=fis.read(bt))!=-1) { 15 fos.write(bt,0,count); 16 } 17 }catch(Exception e) { 18 e.printStackTrace(); 19 }finally { 20 close(fis, fos); 21 } 22 } 23 public static void close(InputStream fis,OutputStream fos) { 24 // 關閉資源 25 try { 26 // 為了防止空指針,需要判斷不為 null 再關閉 27 if (fis!=null) { 28 fis.close(); 29 } 30 } catch (IOException e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 } 34 try { 35 // 為了防止空指針,需要判斷不為 null 再關閉 36 if (fos!=null) { 37 fos.close(); 38 } 39 } catch (IOException e) { 40 // TODO Auto-generated catch block 41 e.printStackTrace(); 42 } 43 } 44 }
Jdk1_7 流的異常處理形式
1 public class Jdk1_7 流的異常處理形式 { 2 public static void main(String[] args) { 3 try( 4 FileInputStream fis=new FileInputStream(new File("src\\com\\ 帶緩沖區的字節流 .java")); 5 FileOutputStream fos=new FileOutputStream(new File("3.java")); 6 ){ 7 /*Scanner sc=new Scanner(System.in); 8 sc.close();*/ 9 byte[] bt=new byte[1024]; 10 int count=0; 11 while((count=fis.read(bt))!=-1) { 12 fos.write(bt,0,count); 13 } 14 }catch (Exception e) { 15 e.printStackTrace(); 16 } 17 Scanner sc1=new Scanner(System.in); 18 String name = sc1.nextLine(); 19 } 20 }
