天天看點

Java_IO流Java_IO流

Java_IO流

文章目錄

  • Java_IO流
    • 1 什麼是IO流
    • 2 IO流的分類
    • 3 IO流體系
    • 4 File類
      • 4.1 構造方法
      • 4.2 成員方法
      • 4.3 應用片段
        • 4.3.1 構造方法
        • 4.3.2 建立檔案夾及檔案
        • 4.3.4 判斷函數
        • 4.3.4 擷取函數
    • 5 字元流讀寫檔案
      • 5.1 按照單個字元讀取檔案
      • 5.2 按數組方式讀取檔案
      • 5.3 用字元流寫資料
    • 6 字元流拷貝檔案
      • 6.1 按單個字元拷貝檔案
      • 6.2 按字元數組拷貝檔案
      • 6.3 字元緩沖流拷貝檔案
    • 7 位元組流拷貝檔案
      • 7.1 按單個位元組拷貝檔案
      • 7.2 按位元組數組拷貝檔案
      • 7.3 用位元組緩沖流拷貝檔案
    • 8 總結

1 什麼是IO流

  I/O,即輸入(Input)、輸出(Output)流,IO流指的是資料像連綿的流體一樣進行傳輸,可以在本地磁盤和網絡上操作資料。百度百科

2 IO流的分類

按照流向分類:

  • 輸入流:将資料讀取到記憶體中
  • 輸出流:将資料從記憶體寫入到指定的檔案中

按照操作分類:

  • 位元組流:以位元組為機關操作資料(InputStream、OutputStream)
  • 字元流:以字元為機關操作資料(Reader、Writer)

3 IO流體系

Java_IO流Java_IO流

菜鳥教程提供的體系圖

4 File類

  一個File對象代表磁盤上的某個檔案或檔案夾。API文檔

4.1 構造方法

  • File(String pathname)
  • File(String parent,String child)
  • File(File parent, String child)

4.2 成員方法

方法名 描述
boolean createNewFile() 建立檔案,不存在就建立,傳回true;存在就不建立,傳回false。
boolean mkdir() 建立單級目錄
boolean mkdirs() 建立多級目錄
boolean isDirectory() 判斷File對象是否為目錄
boolean isFile() 判斷File對象是否為檔案
boolean exists() 判斷File對象是否存在
String getAbsolutePath() 擷取檔案的絕對路徑
String getPath() 擷取檔案的相對路徑
String getName() 擷取檔案名
String[] list() 擷取指定目錄下的所有檔案(夾)名稱數組
File[] listFiles() 擷取指定目錄下所有檔案(夾)File數組

4.3 應用片段

4.3.1 構造方法

//方式一:根據字元串形式的路徑擷取File對象
File file1 = new File("H:\\aaa\\1.txt");
System.out.println("file1:" + file1);
//方式二:根據字元串形式的父目錄以及子目錄建立File對象
File file2 = new File("H:\\aaa","1.txt");
System.out.println("file2:" + file2);
//方式三:根據父目錄對象,以及字元串形式的子目錄來擷取File對象
File file3 = new File("H:\\aaa");
File file4 = new File(file3,"1.txt");
System.out.println("file4:" + file4);
           

運作結果:

file1:H:\aaa\1.txt
file2:H:\aaa\1.txt
file4:H:\aaa\1.txt
           

4.3.2 建立檔案夾及檔案

//建立檔案
File file = new File("h:\\aaa\\2.txt");
boolean flag1 = file.createNewFile();//可能存在異常,路徑不存在或者檔案已經存在
System.out.println("flag1:" + flag1);
//建立檔案夾
File file2 = new File("h:\\aaa\\bbb");
boolean flag2 = file2.mkdir();//建立單級目錄
System.out.println("flag2:" + flag2);
File file3 = new File("h:\\aaa\\bbb\\ccc\\ddd");
boolean flag3 = file3.mkdirs();//建立多級目錄,兩級以上不存在的目錄
System.out.println("flag3:" + flag3);
           

運作結果:

flag1:true
flag2:true
flag3:true
           
  • 使用建立方法時,會存在異常

    IOException

    ,需要進行異常處理。
  • mkdir()

    方法隻能建立單級目錄,也就是說隻能在已存在的檔案夾下建立一級新的檔案夾。
  • mkdirs()

    方法可以建立多級目錄,包括單級目錄。

4.3.4 判斷函數

File file = new File("H:/aaa/bbb");
//判斷是不是檔案夾
System.out.println("檔案夾:" + file.isDirectory());
//判斷是不是檔案
System.out.println("檔案:" + file.isFile());
//判斷是否存在
System.out.println("存在:" + file.exists());
           

運作結果:

檔案夾:true
檔案:false
存在:true
           

4.3.4 擷取函數

項目檔案夾:

Java_IO流Java_IO流
File file1 = new File("lib/1.txt");
//擷取file的絕對路徑
String path1 = file1.getAbsolutePath();
System.out.println("絕對路徑:" + path1);
//擷取file的相對路徑
String path2 = file1.getPath();
System.out.println("相對路徑:" + path2);
//擷取檔案名
String fileName = file1.getName();
System.out.println("檔案名:" + fileName);
System.out.println("--------------分割線-----------");
//擷取lib檔案下的所有檔案(夾):名稱數組
File file2 = new File("lib");
String[] names = file2.list();
for (String name : names) {
  System.out.println(name);
}
System.out.println("--------------分割線-----------");
//擷取lib檔案夾下的所有檔案(夾):File對象數組
File[] files = file2.listFiles();
for (File file : files) {
  System.out.println(file);
}
           

運作結果:

絕對路徑:E:\02_study\18_IDEA\02_project\00_base_object\lib\1.txt
相對路徑:lib\1.txt
檔案名:1.txt
--------------分割線-----------
1.txt
a1
b1
--------------分割線-----------
lib\1.txt
lib\a1
lib\b1
           
  • 擷取的數組隻包含

    lib

    檔案夾下的所有能看到的檔案(夾),不能擷取到子檔案夾内部的檔案。

5 字元流讀寫檔案

成員方法:

函數名 描述
int read() 一次讀取一個字元,傳回值為0~65535(0x00~0xFFFF)的整數。讀取完畢傳回-1
int read​(char[] cbuf) 将字元讀入數組,傳回值為讀取到的字元數。讀取完畢傳回-1

更多成員方法見:API文檔

在工程目錄下準備一個供操作的檔案:lib/1.txt,内容為:你好世界!

5.1 按照單個字元讀取檔案

public static void main(String[] args) throws IOException {
    // 建立字元輸入流對象
    Reader reader = new FileReader("lib/1.txt");
    //定義變量接收讀取得到的字元
    int ch;
    //循環擷取字元
    while ((ch = reader.read()) != -1){
        System.out.println(ch);
    }
    // 釋放資源
    reader.close();
}
           

運作結果:

20320
22909
19990
30028
65281
           
  • int read()

    方法讀取單個字元,傳回值為一個

    0 ~ 65535

    的整數值。
  • 讀取完畢或發生I/O錯誤會進入阻塞狀态,直到遇到下一個可讀取的字元才能繼續讀取。
  • 如果讀取流的末尾,會傳回整數

    -1

5.2 按數組方式讀取檔案

public static void main(String[] args) throws IOException {
	//建立字元輸入流對象
    Reader reader = new FileReader("lib/1.txt");
    //定義字元數組
    char[] chs = new char[3];
    //定義一個變量,記錄讀取到的有效字元數
    int len;
    //循環讀取字元
    while ((len = reader.read(chs)) != -1){
        /*
        chs:表示需要操作的數組
        0:表示起始索引
        len:表示要操作的字元的個數
         */
        System.out.println(len);
        String s = new String(chs,0,len);
        System.out.println(s);
    }
    //釋放資源
    reader.close();
}
           

運作結果:

2
你好
2
世界
1
!
           
  • int read​(char[] cbuf)

    方法傳入的參數為目标字元緩沖數組,将讀取到的字元存入字元數組。傳回值為讀取到的字元個數。字元讀取完後傳回

    -1

5.3 用字元流寫資料

成員方法:

方法名 描述
void write(int c) 一次寫入一個字元
void write​(char[] cbuf) 一次寫入一個字元數組
void write​(String str) 一次寫入一個字元串

更多成員方法見:API文檔

public static void main(String[] args) throws IOException {
        //1. 建立字元輸出流對象
        Writer writer = new FileWriter("lib/1.txt");
        //2. 寫資料
        
        //2.1 一次一個字元
        // writer.write('你');
        // writer.write('好');
        // writer.write('世');
        // writer.write('界');
        // writer.write('!');
        
        //2.2 一次寫一個字元數組
        // char[] chs = {'你','好','世','界','!'};
        // writer.write(chs,0,5);

        //2.3 一次寫一個字元串
        writer.write("你好世界!");
        //3. 釋放資源
        writer.close();
    }
           

6 字元流拷貝檔案

IO流拷貝檔案核心6步:

  1. 建立字元輸入流對象,關聯資料源檔案。
  2. 建立字元輸出流對象,關聯目的地檔案。
  3. 定義變量,記錄讀取到的内容。
  4. 循環讀取,隻要讀取條件滿足就一直讀取,并将讀取到的内容指派給變量。
  5. 将讀取到的資料寫入到目的地檔案中
  6. 釋放資源

6.1 按單個字元拷貝檔案

public static void main(String[] args) throws IOException {
    //1. 建立字元輸入流對象
    Reader reader = new FileReader("lib/1.txt");
    //2. 建立字元輸出流對象
    Writer writer = new FileWriter("lib/2.txt");//如果目的地檔案不存在,則會自動建立
    //3. 定義變量記錄
    int len;
    //4. 循環讀入
    while ((len = reader.read()) != -1){
        //5. 寫入目的地檔案
        writer.write(len);
    }

    //6. 關閉流
    reader.close();
    writer.close();
}
           

6.2 按字元數組拷貝檔案

public static void main(String[] args) throws IOException {
    //1. 建立字元輸入流對象
    Reader reader = new FileReader("lib/1.txt");
    //2. 建立字元輸出流對象
    Writer writer = new FileWriter("lib/2.txt");//如果目的地檔案不存在,則會自動建立
    //3. 定義變量記錄
    char[] chs= new char[1024];
    int len;
    //4. 循環讀入
    while ((len = reader.read(chs)) != -1) {
        //5. 寫入目的地檔案
        writer.write(chs,0,len);
    }
    //6. 關閉流
    reader.close();
    writer.close();
}
           

6.3 字元緩沖流拷貝檔案

public static void main(String[] args) throws IOException {
    //1. 建立字元緩沖輸入流
    BufferedReader br = new BufferedReader(new FileReader("lib/1.txt"));
    //2. 建立字元緩沖輸入流
    BufferedWriter bw = new BufferedWriter(new FileWriter("lib/2.txt"));
    //3. 定義變量,記錄讀取内容
    String str;
    //4. 循環讀取
    while ((str = br.readLine()) != null){
        //5. 寫資料到目的地檔案
        bw.write(str);
        //添加換行符,不同的作業系統有不同的換行符。
        // bw.write("\r\n");//windows系統下的換行符
        //用newLine()方法則不用手動添加換行符
        bw.newLine();
    }
    //6. 釋放資源
    br.close();
    bw.close();
}
           
字元緩沖流:
    分類:
        BufferedReader:字元緩沖輸入流(高效字元輸入流)
            構造方法:public BufferedReader(Reader reader)
            成員方法:public String readLine();   一次讀取一行資料傳回,未讀取到資料傳回null

        BufferedWriter:字元緩沖輸出流(高效字元輸出流)
            構造方法:public BufferedWriter(Writer writer)
            成員方法:public void newLine():根據安全系統給出對應的“換行符”。

        特點:字元緩沖流自帶有緩沖區,大小為8192個字元,16KB
        注意:字元流隻能拷貝純文字檔案。
           
  • 字元輸入緩沖流API
  • 字元輸出緩沖流API

7 位元組流拷貝檔案

7.1 按單個位元組拷貝檔案

public static void main(String[] args) throws IOException {
    //1 建立位元組輸入流,關聯源檔案
    FileInputStream fis = new FileInputStream("lib/tx.png");
    //2 建立位元組輸出流,關聯目的地檔案
    FileOutputStream fos = new FileOutputStream("lib/tx2.png");
    //3 定義變量,用于記錄讀取内容
    int len;
    //4 循環讀取
    while ((len = fis.read()) != -1){
        //5 寫入資料
        System.out.println(len);
        fos.write(len);
    }
    //6 釋放資源
    fis.close();
    fos.close();
}
           
位元組流用法:
    FileInputStream:普通位元組輸入流,用來讀取資料
        構造方法:public FileInputStream(String pathname);
        成員方法:public int read();  一次讀取一個位元組,并傳回讀取到的内容,讀取完畢傳回-1

    FileOutputStream:普通位元組輸出流,用來寫資料。
        構造方法:public FileOutputStream(String pathname);
        成員方法:public void write(int len);  一次寫入一個位元組
           

7.2 按位元組數組拷貝檔案

public static void main(String[] args) throws IOException {
    //1 建立位元組輸入流,關聯源檔案
    FileInputStream fis = new FileInputStream("lib/tx.png");
    //2 建立位元組輸出流,關聯目的地檔案
    FileOutputStream fos = new FileOutputStream("lib/tx3.png");
    //3 定義變量,用于記錄讀取内容
    int len;//讀取到的有效位元組數
    byte[] bytes = new byte[1024];
    //4 循環讀取
    while ((len = fis.read(bytes)) != -1){
        //5 寫入資料
        fos.write(bytes,0,len);
    }
    //6 釋放資源
    fis.close();
    fos.close();
}
           
FileInputStream:普通位元組輸入流,用來讀取資料
        構造方法:public FileInputStream(String pathname);
        成員方法:public int read(byte[] byte);  一次讀取一個位元組數組,并傳回讀取到的内容,讀取完畢傳回-1

FileOutputStream:普通位元組輸出流,用來寫資料。
    構造方法:public FileOutputStream(String pathname);
    成員方法:public void write(byte[] byte,int index ,int len);  一次寫入一個位元組數組
           

7.3 用位元組緩沖流拷貝檔案

public static void main(String[] args) throws IOException {
    //1 建立位元組輸入流,關聯源檔案
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("lib/tx.png"));
    //2 建立位元組輸出流,關聯目的地檔案
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("lib/tx4.png"));
    //3 定義變量,用于記錄讀取内容
    int len;
    //4 循環讀取
    while ((len = bis.read()) != -1){
        //5 寫入資料
        bos.write(len);
    }
    //6 釋放資源
    bis.close();
    bos.close();
}
           
位元組緩沖流用法:
    BufferedInputStream:位元組緩沖輸入流(高效位元組輸入流),用于讀取資料
        構造方法:public BufferedInputStream(InputStream is);
        成員方法:public int read();一次讀取一個位元組,并傳回讀取到的内容

    BufferedOutputStream:位元組緩沖輸出流(高效位元組輸出流),用于寫資料
        構造方法:public BufferedOutputStream(OutputStream os);
        成員方法:public void write(int len); 一次寫入一個位元組

    特點:位元組緩沖流有自己的緩沖區,大小為8192個位元組,8KB

    總結:拷貝純文字檔案使用字元流,拷貝其他檔案(圖檔、音頻、視訊等)使用位元組流。
           

8 總結

  • IO流按流向分為輸出流和輸入流,按資料機關分為字元流和位元組流,按功能分為節點流和處理流
  • 一個File對象代表磁盤上的一個檔案(夾)。
  • 純文字檔案讀寫使用字元流,其它使用位元組流。
  • write()

    方法不會寫入換行符,需使用

    newLine()

    方法進行換行。
  • 字元緩沖流自帶有緩沖區,大小為8192個字元,16KB。隻能讀寫純文字檔案。
  • 位元組緩沖流有自己的緩沖區,大小為8192個位元組,8KB。可以讀寫純文字檔案和非文本檔案。