天天看點

Java IO流IO流流的分類InputStream和ReaderOutputStream 和 Writer處理流用法IO流轉換流推回輸入流

IO流

  • IO流
  • 流的分類
    • 輸入輸出流
    • 位元組流和字元流
    • 節點流和處理流
  • InputStream和Reader
  • OutputStream 和 Writer
  • 處理流用法
  • IO流
  • 轉換流
  • 推回輸入流

IO流

Java IO流是實作輸入/輸出的基礎。

Java把不同的輸入/輸出源(鍵盤,檔案,網絡連接配接等)抽象為"流",Stream。

通過流的方式使用相同的方式來通路不同的輸入/輸出源。

stream是從起源(source)到接收(sink)的有序資料。

傳統流類型都在 java.io 包中。

流的分類

輸入輸出流

按照流的流向分為輸入流和輸出流。是以記憶體的角度來劃分。

輸入流: 隻能讀取資料,不能寫入。由InputStream 和 Reader作為基類

輸出流: 隻能寫入資料,不能讀取。由OutputStream 和 Writer 作為基類

位元組流和字元流

位元組流: 操作資料單元為8位位元組,由 InputStream 和 OutputStream作為基類

字元流:操作資料單元為16位字元,由 Reader 和 Writer 作為基類

節點流和處理流

按角色分為節點流和處理流。

從一個特定的IO裝置(磁盤,或網絡)讀寫資料的流,稱為節點流,節點流也被稱為低級流(Low Level Stream)。

處理流是對節點流的封裝。稱為進階流,包裝流。

使用裝飾器設計模式。

InputStream和Reader

InputStream和Reader都是輸入流的抽象基類。

都實作了下面方法

  • read(): 可以讀取單個字元或位元組,
  • read(byte[] b): 讀取 b.length 個位元組
  • read(byte[] b, int off, int len): 讀取 len 個位元組,從 off 位置開始讀
  • mark(): 記錄指針目前位置記錄一個标記
  • markSupported(): 是否支援 mark操作
  • reset():将指針重新定位到上一次記錄mark的位置
  • skip(): 指針向前移動 n個位元組/字元

FileInputStream 和 FileReader是兩個讀取檔案的輸入流。是 InputStream和 Reader的子類。

FileInputStream fis = new FileInputStream("ReadMe.txt");
        byte[] fbuff = new byte[1024];
        int hasRead = 0;
        while ((hasRead = fis.read(fbuff)) > 0){
            System.out.println(new String(fbuff, 0, hasRead));
        }
        fis.close();
        
           

程式裡打開的 IO資源不屬于記憶體裡的資源, 垃圾回收機制無法回收該資源, 是以要顯式的關閉IO資源,調用 fis.close()。

InputStream 和 Reader都實作了AutoCloseable 接口, 是以可以通過自動關閉資源的 try 語句來關閉IO流。

public abstract class InputStream implements Closeable {
}

public interface Closeable extends AutoCloseable {
}
           

OutputStream 和 Writer

OutputStream 和 Writer都是輸出流的抽象基類。

都提供了下面方法:

  • write(int c): 指定字元/位元組輸出
  • write(byte[] buf): 數組輸出
  • write(byte[] buf, int off, int len): 将數組中 off 開始, 長度為len 輸出

    Writer還包括了支援 String 參數的 writer() 方法。

    FileOutputStream 和 FileWriter 用來檔案輸出。

try (FileInputStream fis1 = new FileInputStream("ReadMe.txt");
             FileOutputStream fos = new FileOutputStream("newFIle.txt")){
            
            byte[] fbuff = new byte[32];
            int hasRead = 0;
            while ((hasRead = fis1.read(fbuff)) > 0){
                fos.write(fbuff, 0, hasRead);
            }

        }
        catch (IOException e){
            e.printStackTrace();
        }
           

關閉輸出流除了保證資源被回收之外,還可以将輸出緩沖區的資料flush到實體節點中。在執行close()之前,自動執行輸出流的flush()。

如果是字元串内容,可以直接使用Writer();

try (FileWriter fileWriter = new FileWriter("t.txt")){

            fileWriter.write("a\r\n");
            fileWriter.write("c test\r\n");
        }
        catch (IOException e){
            e.printStackTrace();
        }
           

處理流用法

使用處理流包裝節點流,對外提供更加友善的輸入/輸出。

節點流的構造器是以實體IO節點為參數的。

處理流的構造器不是實體IO節點,而是已經存在的流。

下面例子 PrintStream 就是處理流,輸出更加友善。

try(FileOutputStream fos = new FileOutputStream("abc.txt");
            PrintStream ps = new PrintStream(fos)){

            ps.println("test字元串");
            ps.println(new FileTest());
        }
        catch (IOException e){
            e.printStackTrace();
        }
           

關閉資源時,隻需要關閉最上層處理流即可, 關閉處理流時,自動關閉該處理流包裝的節點流。

IO流

JAVA IO流體系提供了近40個類。

Java IO流IO流流的分類InputStream和ReaderOutputStream 和 Writer處理流用法IO流轉換流推回輸入流

轉換流

IO展現提供了兩個轉換流, 将位元組流轉換為字元流。

InputStreamReader 将位元組輸入流轉為字元輸入流

OutputStreamWriter 将位元組輸出流轉為字元輸出流

try (InputStreamReader reader = new InputStreamReader(System.in);
             BufferedReader bufferedReader = new BufferedReader(reader)
        ){
            String line = null;
            while ((line = bufferedReader.readLine()) != null){
                if(line.equals("exit")){
                    System.exit(1);
                }
                System.out.println(line);
            }
        }
        catch (IOException e){
            e.printStackTrace();
        }
           

System.in 代表标準輸入,即鍵盤輸入,這個輸入流是 InputStream 類的執行個體, 使用 InputStreamReader 轉為字元輸入流。

将 Reader 包裝為 BufferedReader, 使用它的 readLine() 方法一次讀一行。

推回輸入流

PushbackInputStream, PushbackReader 這兩個是推回輸入流。

提供了 unread () 方法。

這兩個輸入流都帶一個推回緩沖區, 将指定數組内容推回到該緩沖區。

調用 read()時, 先從推回緩沖區讀取, 未裝滿時,再從原緩沖區讀取。

需要指定推回緩沖區的大小, 預設為1。

下面例子找到 test 字元串, 輸出之前的内容

try (PushbackReader pushbackReader = new PushbackReader(new FileReader("abc.txt"), 32)){
            char[] buf = new char[32];
            String lastConntent = "";
            int hasRead = 0;
            while ((hasRead = pushbackReader.read(buf)) > 0){
                String content = new String(buf, 0, hasRead);
                int lastIndex = (lastConntent + content).indexOf("test");

                if(lastIndex > 0){
                    pushbackReader.unread((lastConntent + content).toCharArray());
                    if(lastIndex > 32){
                        buf = new char[lastIndex];
                    }
                    pushbackReader.read(buf, 0, lastIndex);
                    System.out.println(new String(buf, 0, lastIndex));
                    System.exit(0);
                }
                else {
                    System.out.println(lastConntent);
                    lastConntent = content;
                }
            }
        }
        catch (IOException e){
            e.printStackTrace();
        }
           

位址:https://blog.csdn.net/yonggang7/article/details/86776449