節點流(文件流)

節點流

FileReader和FileWriter

字符流(cha[]數組)html

FileReader讀入數據的基本操做

過程

  1. 實例化File類的對象,指明要操做的文件java

    注意:數組

    • 在@Test測試中的相對路徑是相對於當前Module函數

    • 在main函數的相對路徑是相對於當前工程測試

  2. 提供具體的流指針

  3. 數據的讀入過程code

  4. 流的關閉操做視頻

  5. try-catch-finally異常處理htm

說明

  • 必定要注意最後流的關閉
  • read()的理解:返回讀入的一個字符。若是達到文件末尾,返回-1
  • 異常的處理:爲了保證流資源必定能夠執行關閉的操做,須要使用try-catch-finally來處理
  • 讀入的文件(hello.txt)必定要存在,不然會報FileNotFoundException異常

代碼實現

@org.junit.Test
public void test1(){
    FileReader fileReader = null;
    try {
        //1. 實例化File類的對象,指明要操做的文件
        //注意:在@Test測試中的相對路徑是相對於當前Module,在main函數的相對路徑是相對於當前工程
        File file = new File("hello.txt");//相對路徑

        //2. 提供具體的流
        fileReader = new FileReader(file);

        //3. 數據的讀入過程
        //read():返回讀入的一個字符。若是達到文件末尾,返回-1
        //方式一
//      int data = fileReader.read();
//      while(data != -1){
//          System.out.print((char)data);
//          data = fileReader.read();
//      }

        //方式二:語法上針對方式一的修改
        int data;
        while((data = fileReader.read()) != -1){
            System.out.println((char)data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        //4. 流的關閉操做
        try {
            //防止最開始提供流是出現異常致使這裏是空指針,因此加一個判斷
            if(fileReader != null){
                fileReader.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

運行結果

此時的"hello.txt"文檔中存儲的內容是hello對象

o6Ij4.png

使用read()的重載方法

  • read():返回讀入的一個字符。若是達到文件末尾,返回-1
  • read(char[] cbuf):返回每次讀入cbuf數組中的字符的個數。若是達到文件末尾,返回-1(經常使用)
  • read(char cbuf[], int off, int len) (不經常使用)
read(char[] cbuf)的用法
  1. 建立一個char的數組cbuf

    (舉例假定該數組的長度爲5)

    char[] cbuf = new char[5];

  2. 建立len變量,存儲read(char[] cbuf)的返回值

    (注意:返回值即爲每次讀入cbuf數組中的字符的個數)

  3. 讀取數據

    • 寫法一:循環遍歷
    for (int i = 0; i < len; i++) {
        System.out.print(cbuf[i]);
    }
    • 寫法二:char[]類型和String類型轉換
    String str = new String(cbuf,0,len);
    System.out.print(str);

    http://www.javashuo.com/article/p-pzykigqu-mx.html

    o91I2.png

  4. 流的關閉操做(不要忘記)

read(char[] cbuf)讀取數據時的注意事項
  • 寫法一

    for (int i = 0; i < len; i++) {
        System.out.print(cbuf[i]);
    }

    其中for循環時,i必定要小於len(每次讀入cbuf數組中的字符的個數)而不是cbuf.length

    • 畫圖說明:

      o9xOe.png

      最後還剩下3個數據的時候:

      • 若是for循環中的i小於cbuf.length(錯誤的寫法)

        o9rpk.png

        最後的輸出爲:helloWorld123ld

        (其中hello爲第一次的結果,World爲第二次的結果,123ld爲第三次的結果)

        而文件中的內容爲helloWorld123,因此此時的寫法是錯誤的

      • 若是for循環中的i小於len(正確的寫法)
        o9Ogn.png

        最後的輸出爲:helloWorld123

        (其中hello爲第一次的結果,World爲第二次的結果,123爲第三次的結果)

  • 寫法二

    String str = new String(cbuf,0,len);
    System.out.print(str);

    其中利用了String(char[] value, int offset, int count)構造器,而不是String(char[] value)構造器

    • String(char[] value)構造器(錯誤的寫法)
      錯誤緣由與寫法一錯誤的方法相同

    • String(char[] value, int offset, int count)構造器(正確的寫法)

      讀取char[]數組中角標0到角標len的內容,過程與寫法一正確的方法過程相似

FileReader寫出數據的基本操做

過程

  1. 實例化File類的對象,指明要操做的文件
  2. 提供具體的流
  3. 數據的寫出過程
  4. 流的關閉操做
  5. try-catch-finally異常處理

說明

寫出操做,對應的File能夠不存在。

  • 若是不存在,在寫出的過程當中,會自動建立此文件
  • 若是存在這個文件
    • 對原有文件的覆蓋

      流使用的構造器爲

      FileWriter(file, false)

      或者是

      FileWriter(file)

    • 在原有文件的基礎上追加內容(不會對原有文件進行覆蓋)

      流使用的構造器爲

      FileWriter(file, true)

o9TfM.png

代碼實現

FileWriter fw1 = null;
FileWriter fw2 = null;
try {
    //1. 提供File類的對象,指明寫出到的文件
    File file = new File("hi.txt");

    //2. 提供FileWriter的對象,用於文件的寫出
    //覆蓋
    fw1 = new FileWriter(file,false);
    //不覆蓋
    fw2 = new FileWriter(file,true);
    //3. 寫出的操做
    fw1.write("I have a dream!\n");
    fw2.write("123\n");
} catch (IOException e) {
    e.printStackTrace();
}finally {
    //4. 關閉流資源
    if(fw1 != null)
        try {
            fw1.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fw2 != null)
                try {
                    fw2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        } 
}

運行結果

最開始hi.txt文件中的內容爲hello
運行代碼後
o9VQa.png

使用FileWriter和FileReader實現文本文件的複製

過程

  1. 建立File類的對象,指明讀入和寫出的文件
  2. 建立輸入流和輸出流的對象
  3. 數據的讀入和寫入操做
  4. 關閉流資源
  5. try-catch-finally異常處理

說明

  • 在讀取文件文件時,選擇read(char[] cbuf)的用法

  • 在寫入文件的時候,注意不要寫成

    fw.write(cbuf);

    此時出現的錯誤和讀取操做時寫法一會出現的錯誤相同,不能夠正確的讀取文件中本來的內容

    須要使用

    fw.write(cbuf,0,len);

    讀取cbuf數組中角標爲0的元素到角標爲len的元素

  • 在最後關閉流資源的時候,必定要注意兩個流都要關閉,即便其中一個流在關閉的時候拋出異常另外一個流也要關閉

    有兩種寫法

    • 寫法一
    finally {
        //4. 關閉流資源
        if(fr != null)
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(fw != null)
                    try {
                        fw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
    }
    • 寫法二
    finally {
        //4. 關閉流資源
        try {
            if(fr != null)
                fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        try {
            if(fw != null)
                fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

代碼實現

public void test4(){
    FileReader fr = null;
    FileWriter fw = null;
    try {
        //1. 建立File類的對象,指明讀入和寫出的文件
        File file1 = new File("hello.txt");
        File file2 = new File("hi.txt");
        //2. 建立輸入流和輸出流的對象
        fr = new FileReader(file1);
        fw = new FileWriter(file2,true);
        //3. 數據的讀入和寫入操做
        char[] cbuf = new char[5];
        int len;//記錄每次讀入到cbuf數組中字符的個數
        while((len = fr.read(cbuf)) != -1){
            //每次寫出len個字符
            fw.write(cbuf,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        //4. 關閉流資源
        try {
            if(fr != null)
                fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            if(fw != null)
                fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

運行結果

oG51G.png

注意

字符流不能處理圖片文件等字節數據!!!

FileInputStream和FileOutputStream

字節流(byte[])

使用FileInputStream和FileOutputStream實現文本文件的複製

過程

  1. 建立File類的對象,指明讀入和寫出的文件
  2. 建立輸入流和輸出流的對象
  3. 數據的讀入和寫入操做
  4. 關閉流資源
  5. try-catch-finally異常處理

代碼實現

FileInputStream fis = null;
FileOutputStream fos = null;
try {
    File srcfile = new File("殷志源.png");
    File destfile = new File("丸子.png");

    fis = new FileInputStream(srcfile);
    fos = new FileOutputStream(destfile);

    byte[] buffer = new byte[5];
    int len;
    while((len = fis.read(buffer)) != -1){
        fos.write(buffer,0,len);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if(fis != null)
            fis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        if(fos != null)
            fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

運行結果

oRznG.png
oRHMT.png

指定路徑下文件的複製的方法

複製視頻

public void copyFile(String srcPath, String destPath){
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        File srcfile = new File(srcPath);
        File destfile = new File(destPath);

        fis = new FileInputStream(srcfile);
        fos = new FileOutputStream(destfile);

        byte[] buffer = new byte[1024];
        int len;
        while((len = fis.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(fis != null)
                fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            if(fos != null)
                fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ocIS1.png

od4o2.png

字節流和字符流使用的注意事項

  • 對於文本文件(.txt, .java, .c, .cpp......),使用字符流來處理
  • 對於非文本文件(.jpg, .mp3, .mp4, .avi, .doc, .ppt......),使用字節流來處理
  • 若是隻是想複製文本文件,也能夠使用字節流(流在此時只是個搬運的做用)
  • 非文本只能夠用字節流操做
相關文章
相關標籤/搜索