JAVA中IO流詳解


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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM