Java 基礎(十)字節流

字節流-InputStream 和 OutputStream

上篇文章咱們講了字符流的基本操做,而且經過閱讀源碼咱們知道,字符流就是基於字節流作的實現——一次讀取兩個字節組成一個字符。java

InputStream

此抽象類是表示字節輸入流的全部類的超類。數組

須要定義 InputStream 子類的應用程序必須老是提供返回下一個輸入字節的方法。bash

方法名 方法描述
available() 返回此出入流下一個方法調用能夠不受阻塞地今後輸入流讀取估計字節數
close() 關閉此輸入流並釋放與該流相關聯的全部系統資源
mark(int readlimit) 在此輸入流中標記當前的位置
markSupported() 此時此輸入流是否支持 mark 和 reset 方法
read() 從輸入流中讀取數據的下一個字節
read(byte[] b) 從輸入流中讀取必定數量的字節,並將其存儲在緩衝區數組b 中。
reset() 將此流從新定位到最後一次對此輸入流調用 mark 方法時的位置
skip(long n) 跳過和丟棄此輸入流數據的 n 個字節

OutputStream

此抽象類是表示輸出字節流的全部類的超類。輸出流接受輸出字節並將這些字節發送到某個接收器。ide

須要定義 OutputStream 子類的應用程序必須始終提供至少一種可寫入一個輸出字節的方法。學習

方法名 方法描述
close() 關閉此出入流並釋放與此流有關的全部系統資源
flush() 刷新此輸出流並強制寫出全部緩衝的輸出字節
write(byte[] b) 將 b.length 個字節從指定的 byte 數組寫入此輸出流
write(int b) 將指定字節寫入此輸出流

FileInputStream 和 FileOutputStream

仍是以以前那個文件讀寫的 demo 爲例,咱們先看一下字節流怎麼玩的~ui

try {
        // 建立讀取流和寫入流
        FileInputStream fis = new FileInputStream("raw.txt");
        FileOutputStream fos = new FileOutputStream("target.txt");
        // 讀取單個字符,自動往下讀
        byte[] buf = new byte[1024];
        int len;
        while ((len = fis.read(buf)) != -1) {
            fos.write(buf, 0, len);
        }
        fis.close();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
}複製代碼

使用 I/O 複製圖片

這個操做和上面的代碼同樣,注意圖片是二進制數據,只能使用字節流讀取,不能使用字符流哦。this

字節流緩衝區

這個和字符流緩衝區基本沒差了,直接貼代碼吧~spa

try {
        // 建立讀取流和寫入流
        FileInputStream fis = new FileInputStream("raw.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        FileOutputStream fos = new FileOutputStream("target.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        // 讀取單個字符,自動往下讀
        byte[] buf = new byte[1024];
        int len;
        while ((len = bis.read(buf)) != -1) {
            bos.write(buf, 0, len);
        }
        bis.close();
        bos.close();
    } catch (IOException e) {
        e.printStackTrace();
}複製代碼

字節流拷貝video 等大文件

  • 除文本文件以外必須使用字節流
  • 文件比較大的必須使用緩衝區提高效率

代碼就補貼了,同上。code

自定義字節流緩衝區

這個和自定義字符流緩衝區同樣,實現思想就再也不贅述了,不記得的同窗請翻上一篇筆記。對象

直接貼代碼吧,沒什麼特別的。

class MyBufferedImputStream {
    private InputStream in;
    private byte[] buf = new byte[1024 * 8];
    private int pos = 0;
    private int count = 0;

    public MyBufferedImputStream(InputStream in) {
        this.in = in;
    }

    // 從緩衝區一次讀一個字節
    public int read() throws IOException {
        // 經過in對象讀取硬盤上的數據,存儲在buf
        if (count == 0) {
            count = in.read(buf);
            if (count < 0)
                return -1;
            byte b = buf[pos];
            count--;
            pos++;
            return b;
        } else if (count > 0) {
            byte b = buf[pos];
            pos++;
            count--;
            return b;
        }
        return -1;
    }

    //關閉流
    public void myClose() throws IOException {
        in.close();
    }
}複製代碼

讀取鍵盤錄入

這個好像超綱了,Android 並不須要讀取鍵盤錄入。至於 EditText 是怎麼讀取鍵盤錄入的,咱們之後學習 EditText 源碼的時候再慢慢研究。

Java 裏面讀取鍵盤錄入主要用的是InputStream in = System.in;,有須要的小夥伴自行研究吧。

轉換流 InputStreamReader 和 OutputStreamWriter

java中須要轉換流就會使用到轉換流,使用到了 InputStreamReader/OutputStreamWriter。

咱們前面也說了 FileReader 繼承自InputStreamReader,內部構造方法 new FileInputStream(),所以,咱們知道字符流就是字節流使用了轉換流。

仍是寫一下代碼吧,順便講一下上面提到的鍵盤錄入

//獲取鍵盤錄入對象
InputStream in = System.in;
//轉換
InputStreamReader isr = new InputStreamReader(in);
//提升效率
BufferedReader bur = new BufferedReader(isr);
String line;
try {
    while ((line = bur.readLine()) != null) {
        if (line.equals("over"))
            break;
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}複製代碼

沒什麼意思,寫入轉換流也是同樣的操做,我就不寫了。

流操做的規律

  • 讀取大文件記得用字*流緩衝區提升效率
  • 讀取文本文件優先使用字符流、其他一律用字節流
  • 文件讀寫操做通常都是使用 FileInput(Output)Stream。
相關文章
相關標籤/搜索