Java總結IO篇之字節流與字符流轉化

本篇接上篇:Java中的字符流,流的讀寫的細節參考上篇
本篇講述字節流相關話題,包括字節流的讀取與寫出,字節流轉化爲字符流
1.明確是不是純文本:純文本 ? 字符流: 字節流
2.明確數據來源( 輸入流 I )和數據流向( 輸出流 O )
3.I流和O流對接,數據傳輸
另外:須要字符編碼轉換,使用字節流轉換字符流java

數據來源( 輸入流 I ):內存、磁盤、網絡、鍵盤    
數據流向( 輸出流 O ): 內存、磁盤、網絡、控制檯
1.最多見的幾種流
9414344-51ddbaea0edd3a1d.png
最多見的幾種流.png
2.流與流之間的相互做用:轉換與包裝
9414344-1bae611af7db90b2.png
轉換流和包裝流.png

1、FileOutputStream與FileInputStream

1.FileOutputStream:輸出流,寫出操做
FileOutputStream fos = null;
 try {
     String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\FileInputStream.txt";
     fos = new FileOutputStream(fileName);
     fos.write("Line1 第一行".getBytes());//不須要刷新緩衝
 } catch (IOException e) {
     e.printStackTrace();
 } finally {
     try {
         if (fos != null) {
             fos.close();
         }
     } catch (IOException e) {
         e.printStackTrace();
     }
 }
9414344-489cac370aad7f6d.png
字節輸出流.png

2.FileInputStream:輸入流,讀進操做
public static void main(String[] args) {
    try {
        String fileName = "I:\\Java\\Base\\Thinking\\src\\IOTest\\FileInputStream.txt";
        FileInputStream fis = new FileInputStream(fileName);
        //readOneByOne(fis);
        //readByByteArrayByWhile(fis);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
1)一個一個字節
private static void readOneByOne(FileInputStream fis) throws IOException {
    int ch = 0;
    while ((ch = fis.read()) != -1) {
        System.out.println(ch + "=" + (char) ch);
    }
}

一共輸出了15個字節,和Line1 第一行有出入,緣由:
在utf-8編碼下,一箇中文字符佔三個字節git

76=L  105=i  110=n  101=e  49=1  32=   231=ç  172=¬  172=¬  228=ä  184=¸  128=�  232=è  161=¡  140=�
2)字節數組方式:
private static void readByByteArrayByWhile(FileInputStream fis) throws IOException {
    //字符數組循環讀取
    byte[] buf = new byte[8];
    int len = 0;
    while ((len = fis.read(buf)) != -1) {
        System.out.println(new String(buf, 0, len));
    }
}

可見buf一次裝個字節,由三個字節表示,被分紅了兩半,因此讀出了亂碼github

//Line1 �
//�一行
文件字節數
System.out.println(fis.available());//15

2、使用字節流拷貝

視頻大小:576M編程

1.使用FileInputStream和FileInputStream拷貝

耗時:6.162444569秒數組

private static void copy() {
    FileOutputStream fos = null;
    FileInputStream fis = null;
    try {
        fis = new FileInputStream("I:\\Java\\Base\\Thinking\\src\\IOTest\\video.avi");
        fos = new FileOutputStream("F:\\javaTest\\IO\\video.avi");
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len = fis.read(buf)) != -1) {
            fos.write(buf, 0, len);
        }
    } catch (Exception 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();
        }
    }

2.使用包裝類BufferedOutputStream和BufferedInputStream拷貝:

方法耗時:33.478968503秒微信

private static void copyByBuf() {
    BufferedOutputStream bfos = null;
    BufferedInputStream bfis = null;
    try {
        FileInputStream fis = new FileInputStream("I:\\Java\\Base\\Thinking\\src\\IOTest\\video.avi");
        bfis = new BufferedInputStream(fis);
        FileOutputStream fos = new FileOutputStream("F:\\javaTest\\IO\\video.avi");
        bfos = new BufferedOutputStream(fos);
        int b = 0;
        while ((b = bfis.read()) != -1) {
            bfos.write(b);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (bfis != null) {
                bfis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (bfos != null) {
                bfos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3、字節流轉化爲字符流

場景一:將鍵盤錄入寫入到本地磁盤
分析:鍵盤錄入是一個字節輸入流: InputStream in = System.in;
因爲輸入的都是字符,使用字符流將比較方便(固然字節流也能夠,不過麻煩一點)
1.用字符流InputStreamReader將字節流轉化
2.再用字符包裝流BufferedReader包裝一下(固然也能夠不包裝,不過麻煩一點)
9414344-1bae611af7db90b2.png
轉換流和包裝流.png
public class Save2File {
    public static void main(String[] args) throws Exception {

        //數據源----鍵盤錄入字節流轉化爲字符流後包裝成BufferedReader
        BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\鍵盤錄入";
        //數據流向 :"I:\\Java\\Base\\Thinking\\src\\IOTest\\鍵盤錄入" 文件
        BufferedWriter brw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)));

        String line = null;
        while ((line=bfr.readLine())!=null){
            if ("over".equals(line)) {
                break;
            }
            brw.write(line);
            brw.newLine();
            brw.flush();
        }
        bfr.close();
        brw.close();
    }
}
9414344-b0dfa3726a76811e.png
鍵盤錄入到文件.png
場景二:將鍵盤錄入寫入到本地磁盤:指定字符編碼

默認字符編碼爲utf-8,這裏使用GBK測試網絡

public class Save2File {
    public static void main(String[] args) throws Exception {
        //數據源----鍵盤錄入字節流轉化爲字符流後包裝成BufferedReader
        BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\鍵盤錄入-GKB";
        //數據流向 :"I:\\Java\\Base\\Thinking\\src\\IOTest\\鍵盤錄入" 文件
        BufferedWriter brw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path),"GBK"));

        String line = null;
        while ((line=bfr.readLine())!=null){
            if ("over".equals(line)) {
                break;
            }
            brw.write(line);
            brw.newLine();
            brw.flush();
        }
        bfr.close();
        brw.close();
    }
}
9414344-4c519228680a3a3e.png
GBK存儲.png

可見二者的字節數不一樣,一個GBK的漢字佔2個字節(2*5+\r\n=12) ,一個UTF-8漢字佔3個字節(3*5+\r\n=17)ide

場景3:讀取文件輸出到控制檯
分析:控制檯輸出是一個字節輸出流:PrintStream out = System.out;
因爲輸出的都是字符,使用字符流將比較方便(固然字節流也能夠,不過麻煩一點)
1.用字符流OutputStreamWriter將字節流轉化
2.再用字符包裝流BufferedWriter包裝一下(固然也能夠不包裝,不過麻煩一點)
public class ReadFile2Console {
    public static void main(String[] args) throws Exception {
        //數據源----本地文件
        String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md";
        BufferedReader bfr = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
        //數據流向 :"I:\\Java\\Base\\Thinking\\src\\IOTest\\鍵盤錄入" 文件
        BufferedWriter brw = new BufferedWriter(new OutputStreamWriter(System.out));
        String line = null;
        while ((line = bfr.readLine()) != null) {
            if ("over".equals(line)) {
                break;
            }
            brw.write(line);
            brw.newLine();
            brw.flush();
        }
        bfr.close();
        brw.close();
    }
}
9414344-e9614229e272ca27.png
文件輸出到控制檯.png
場景4:改變系統流的流向

能夠改變系統的錄入流(數據來源),和控制檯輸出流(數據流向)測試

System.setIn(InputStream 輸入流); 自定義System.in數據來源(默認鍵盤錄入)
System.setOut(PrintStream 輸出流);自定義System.out數據流向(默認控制檯)
public class ReadFile2Console {
    public static void main(String[] args) throws Exception {
        //數據源----本地文件
        String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md";

        System.setIn(new FileInputStream(path));//將鍵盤源改成了磁盤文件源
        System.setOut(new PrintStream("F:\\hell.txt"));//將流向控制檯改成流向磁盤文件

        BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        //數據流向 :"I:\\Java\\Base\\Thinking\\src\\IOTest\\鍵盤錄入" 文件
        BufferedWriter brw = new BufferedWriter(new OutputStreamWriter(System.out));
        String line = null;
        while ((line = bfr.readLine()) != null) {
            if ("over".equals(line)) {
                break;
            }
            brw.write(line);
            brw.newLine();
            brw.flush();
        }
        bfr.close();
        brw.close();
    }
}

後記:捷文規範

1.本文成長記錄及勘誤表
項目源碼 日期 備註
V0.1--無 2018-10-10 Java中的字節流與字符流轉化
V0.2--無 - -
2.更多關於我
筆名 QQ 微信 愛好
張風捷特烈 1981462002 zdl1994328 語言
個人github 個人簡書 個人CSDN 我的網站
3.聲明

1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大編程愛好者共同交流
3----我的能力有限,若有不正之處歡迎你們批評指證,一定虛心改正
4----看到這裏,我在此感謝你的喜歡與支持網站

相關文章
相關標籤/搜索