IO 流之字節流和轉換流


  • 基本讀取操作:

    • InputStream();
    • OutputStream(); // 直接寫入目的地中, 不需要 flush() 刷新
      • write(byte[] b); // 參數為 byte 數組
  • 字符流不能操作媒體文件, 因為字符流讀入文件后, 需要對照編碼表.
    如果編碼表中沒有對應的數據, 這時, 碼表會用一些未知字符區的編碼替代,最終,會發生錯誤.

// 示例一: 寫入數據

    // 1. 創建字節輸出流對象, 用於操作文件
        FileOutputStream fos = new FileOutputStream("demo.js");

    //2. 寫入數據, 注意寫入的為 byte 類型, 並且直接寫入到目的地中, 不需要 flush()
        fos.write("abc".getBytes());

    //3, 關閉資源
        fos.close();


// 示例二: 讀取數據

    // 1, 創建讀取流對象, 和指定文件關聯
        FileInputStream fis = new FileInputStream("demo.js");

    // 2. 讀取字節數組
        byte[] buf = new byte[1024];

        int len = 0;
        while((ch=fis.read(buf)) != -1){
            System.out.println(new String(buf,0,len));
        }

    /*
     * // 一次讀取一個字節
     *     int ch = 0;
     *     while((ch=fis.read()) != -1){
     *         System.out.println((char)ch);
     *      }
     */

     // 3. 關閉流
        fis.close();

      // 備注: fis.available(); 可以獲取文件大小


// 示例三: 復制一個 mp3 媒體文件

    public static void copyMp3() throws IOException {
        FileInputStream fis = new FileInputStream("demo.mp3");
        BufferedInputStream bufis = new BufferedInputStream(fis);

        FileOutputStream fos = new FileOutputStream("my.mp3");
        BufferedOutputStream bufos = new BufferedOutputStream(fos);

        /*
         *  byte[] buf = new byte[1024];
         *
         *  int len = 0;
         *  while((len=bufis.read(buf))!=-1){
         *       bufos.write(buf,0,len);
         *       bufos.flush();   // 使用緩沖區的讀, 每次讀完后, 需要刷新
         * }
         */

        // 緩沖區讀取單個字符
         int ch = 0;
         while((ch=bufis.read())!=-1){
            bufos.write(ch);
         }

        bufos.close();
        bufis.close();
    }

// 示例四: 讀取一個鍵盤錄入的數據, 並將數據變成大寫顯示在控制台上,
        // 如果用戶輸入的是 over, 結束鍵盤錄入

    /* 分析:
     *    鍵盤本身就是一個標准的輸入設備,
     *    對於 java 而言, 對於這種輸入設備都有對應的對象.
     *    鍵盤錄入對應的對象位於 java.lang 包中的 System 類
     *     "in" : 標准輸入
     *     "out" : 標准輸出
     * 思路:
     *     1. 因為鍵盤錄入只讀取一個字節, 要判斷是否是 over, 需要將讀取到的字節拼成字符串
     *     2. 那就需要一個容器, StringBuilder
     *     3. 在用戶回車之前, 將錄入的數據變成字符串判斷即可
     *   
     * 步驟:
     *     1. 創建容器
     *     2. 獲取鍵盤讀取流
     *     3. 定義變量記錄讀取到的字節, 並循環獲取
     *     4. 將讀取到的字節存儲到 StringBuilder 中
     *     5. 在存儲之前需要判斷是否是換行標記, 因為換行標記不存儲
     */

     public static void readKey() throws IOException{

        // 1. 創建容器
            StringBulider sb = new StringBuilder();

        // 2. 獲取鍵盤讀取流
            InputStream in = System.in;

        // 3. 定義變量記錄讀取到的字節, 並循環獲取
            int ch = 0;

            while((ch=in.read())!=-1){
                // 在存儲之前需要判斷是否是換行標記, 因為換行標記不存儲
                if(ch=='\r')
                    continue;
                if(ch=='\n'){
                    String temp = sb.toString();
                    if("over".equals(temp))
                        break;
                    System.out.println(temp.toUpperCase());
                    sb.delete(0,sb.length());  // 每次輸出后,需要清空 StringBuilder 容器.
                                               // 集合的清空用 clear
                }
                else{
                    sb.append((char)ch); // 需要變成字符存儲進容器
                }
            }
        }

轉換流

  1. 將字節流轉換為字符流的橋梁: InputStreamReader(); 相當於解碼
  2. 將字符流轉換為字節流的橋梁: OutputStreamWriter(); 相當於編碼
  3. 轉換過程中,可以指定編碼表
// 示例四: 讀取一個鍵盤錄入的數據, 並將數據變成大寫顯示在控制台上,
        // 如果用戶輸入的是 over, 結束鍵盤錄入

    public static void readKey() throws IOException{

        // 字節流
        InputStream in = System.in;

        // 將字節流轉換為字符流
        InputStreamReader isr = new InputStreamReader(in);

        // 緩沖區修飾字符流
        BufferedReader bufr = new BufferedReader(isr);

        // 獲取輸出流
        OutputStream out = System.out;

        // 將字符流轉換為字節流, 構造函數可以接收 字節流
        OutputStreamWriter osw = new OutputStreamWriter(out);
        BufferedWriter bufw = new BufferedWriter(osw);

        String line = null;
        while((line=bufr.readLine())!=null){
            if("over".equals(line))
                break;
            // System.out.println(line.toUpperCase());

            // 每次讀取到的 line 是字符, 將字符寫入到字節輸入流中, 需要用到 OutputStreamWriter
            bufw.write(line.toUpperCase());
            bufw.newLine(); // 換行
            bufw.flush();  // 每次寫入后,需要刷新. 將流中的數據刷到控制台上
        }
    }

    // 升級版本:
    BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));


參考資料


免責聲明!

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



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