Java BIO

BIO

IO:input/output
input:從磁盤讀到內存
output:從內存存到磁盤
Java中IO分爲:字節流和字符流
linux

字節流

一切文件數據在存儲時,都是以二進制數字的形式保存git

OutputStream

全部的輸出流都繼承自java.io.OutputStream類,OutputStream是一個抽象類直接繼承Java.lang.Object超類
已知直接子類:ByteArrayOutputStream , FileOutputStream , FilterOutputStream , ObjectOutputStream , OutputStream , PipedOutputStreamgithub

  • 公共方法:數組

    void close() 關閉此輸出流並釋放與此流相關聯的任何系統資源。
    void flush() 刷新此輸出流並強制任何緩衝的輸出字節被寫出。
    void write(byte[] b) 將 b.length字節從指定的字節數組寫入此輸出流。
    void write(byte[] b, int off, int len) 從指定的字節數組寫入 len個字節,從偏移 off開始輸出到此輸出流。
    abstract void write(int b) 將指定的字節寫入此輸出流。緩存

FileOutputStream

FileOutputStream文件字節輸出流,做用就是將內存中的數據寫入磁盤文件app

  • 構造方法編碼

    FileOutputStream(File file) 建立文件輸出流以寫入由指定的 File對象表示的文件。
    FileOutputStream(File file, boolean append) 建立文件輸出流以寫入由指定的 File對象表示的文件。若是append爲true則在文件末尾寫入
    FileOutputStream(FileDescriptor fdObj) 建立文件輸出流以寫入指定的文件描述符,表示與文件系統中實際文件的現有鏈接。
    FileOutputStream(String name) 建立文件輸出流以指定的名稱即路徑中寫入文件。
    FileOutputStream(String name, boolean append) 建立文件輸出流以指定的名稱即路徑中寫入文件。指針

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class IO_FileOutputStream {

    FileOutputStream FOS = null;

    /**
     * FOS使用:
     *     1.建立FOS,並傳入String path 輸出路徑,若是路徑不存在,文件沒法打開等就會拋出FIleNotFoundException
     *     2.FOS.write() 寫入數據
     *     3.關閉資源
     * @param path
     * @throws IOException
     */
    void fos( String path ) throws IOException {
        FOS = new FileOutputStream(path);
        //輸出結果97--a,由於是以字節輸出的
        FOS.write(97);

        /**
         * FOS輸入都是字節byte型(-128~127之間),當第一個是負數時則會和後面一個數一塊兒組成一箇中文編碼默認GBK,GBK-2字節-1中文;UTF-3-1中文
         */
        byte[] bytes = new byte[]{12, 3, 34, 48, 49,126};
        FOS.write(bytes);
        FOS.write(10);//10就是換行符

        /**
         *  換行win:\r\n
         *  linux:/n
         *  ma:/r
        */

        FOS.write("\r\n".getBytes());

        /**
         * 從byte數字的第off位開始讀入長度len的byte數據寫入
         *
         */
        FOS.write(bytes, 1, 2);
        FOS.write(10);//10就是換行符

        /**
         * 若是是字符串,能夠使用String的 byte[] getBytes()方法來轉換成byte數組
         */
        byte[] bytes1 = "Hello".getBytes();
        System.out.println(Arrays.toString(bytes1));
        FOS.write(bytes1);


        FOS.close();
    }

    public static void main( String[] args ) throws IOException {
        IO_FileOutputStream fos = new IO_FileOutputStream();
        fos.fos("./src/JavaCore/IO/FOS.txt");
    }
}

InputStream

java.io.InputStream全部輸入流的頂層類code

方法:
int read()----讀取一個字節,返回0到65535( 0x00-0xffff )範圍內的整數
回,每讀取一個指針就日後移一位,若是到達末尾則返回-1
int read(byte[] b)----從輸入流中讀取一些字節並緩存到b中,到達末尾返回-1,並返回緩衝區b的總字節數
int read(byte[] b,int off,int len)----
void close()----關閉流並釋放與流關聯的任何系統資源

FileInputStream

與FileOutputStream相對,FileInoutStream將硬盤中的數據讀入內存

構造方法

FileInputStream(File file) 經過打開與實際文件的鏈接建立一個 FileInputStream ,該文件由文件系統中的 File對象 file命名。
FileInputStream(FileDescriptor fdObj) 建立 FileInputStream經過使用文件描述符 fdObj ,其表示在文件系統中的現有鏈接到一個實際的文件。
FileInputStream(String name) 經過打開與實際文件的鏈接來建立一個 FileInputStream ,該文件由文件系統中的路徑名 name命名。

public class IO_FileInputStream {

    FileInputStream FIS = null;

    /**
     * FIS使用:read()
     * 1.新建FIS對象
     * 2.read
     * 3.close
     * @param path
     * @throws IOException
     */
    void fis( String path ) throws IOException {
        FIS = new FileInputStream(path);

        int len;
        while ((len = FIS.read()) != -1) {
            System.out.print((char)len);
        }

        FIS.close();
        System.out.println();
        System.out.println("-------------------------");
        /**
         * 注意循環不能寫成下面這樣,由於在read時每讀取一個指針就會自動日後移,這樣讀就會跳過不少數據,致使讀取不徹底
         */
        FileInputStream fis = new FileInputStream("./src/JavaCore/IO/FIS.txt");
        while (fis.read() != -1) {
            System.out.print((char)fis.read());
        }
        fis.close();
    }

    /**
     * 使用byte[]來緩存讀取到的字節,int read(byte[])返回的就是讀取到的有效字節長度
     * @param path
     * @throws IOException
     */
    void fis_arrayBuff( String path ) throws IOException {
        FIS = new FileInputStream(path);
        byte[] bytes = new byte[1024];
        int len;
        while ((len = FIS.read(bytes)) != -1) {
            //String的構造方法中能夠傳入一個byte來生成,這裏指定了開始位和長度,否則後面會有許多空格,由於1024長度的byte,
            //len長度以後的都是0
            System.out.println(new String(bytes, 0, len));
        }
    }

    public static void main( String[] args ) throws IOException {
        IO_FileInputStream iofis = new IO_FileInputStream();
        iofis.fis_arrayBuff("./src/JavaCore/IO/FIS.txt");

    }
}

字符流

Reader

public abstract class Reader extends Object----全部字符輸入流的頂層類
直接的子類:
BufferedReader , CharArrayReader , FilterReader , InputStreamReader , PipedReader , StringReader

共有方法:

abstract void close() -----關閉流並釋放與之相關聯的任何系統資源。
void mark(int readAheadLimit) ------標記流中的當前位置。
boolean markSupported() ----------告訴這個流是否支持mark()操做。
int read() ---------------讀一個字符 返回0到65535( 0x00-0xffff )範圍內的整數,若是已經達到流的末尾,則爲-1
int read(char[] cbuf) ----將字符讀入數組cbuf 返回讀取的字符數,若是已經達到流的結尾,則爲-1
abstract int read(char[] cbuf, int off, int len) ---------將字符讀入數組的一部分。
int read(CharBuffer target) ------------- 嘗試將字符讀入指定的字符緩衝區。
boolean ready() -------------告訴這個流是否準備好被讀取。

FileReader

FileReader是用於讀取字符流,繼承關係:java.lang.Object <-java.io.Reader <-java.io.InputStreamReader <-java.io.FileReader

示例:

public static void main( String[] args ) throws IOException {

        FileReader fr = new FileReader("./src/JavaCore/IO/FOS.txt");

        /**
         * 讀取單個字符
         */
//        int len;
//        while ((len = fr.read()) != -1) {
//            System.out.print((char) len);
//        }

        /**
         * 讀取多個字符
         */
        char[] cs = new char[1024];
        int len;
        while ((len = fr.read(cs)) != -1) {

            System.out.println(new String(cs,0,len ));
        }

        fr.close();
    }

Writer

public abstract class Writer extends Object implements Appendable, Closeable, Flushable

Writer用於寫入字符流的抽象類,是全部輸出字符流的父類。 子類必須實現的惟一方法是write(char [],int,int),flush()和close()。 然而,大多數子類將覆蓋這裏定義的一些方法,以便提供更高的效率,附加的功能或二者

Writer append(char c)
將指定的字符附加到此做者。
Writer append(CharSequence csq)
將指定的字符序列附加到此做者。
Writer append(CharSequence csq, int start, int end)
將指定字符序列的子序列附加到此做者。
abstract void close()
關閉流,先刷新。
abstract void flush()
刷新流。
void write(char[] cbuf)
寫入一個字符數組。
abstract void write(char[] cbuf, int off, int len)
寫入字符數組的一部分。
void write(int c)
寫一個字符
void write(String str)
寫一個字符串
void write(String str, int off, int len)
寫一個字符串的一部分。

FileWriter

FileWriter的繼承關係:

java.lang.Object
java.io.Writer
java.io.OutputStreamWriter
java.io.FileWriter

構造方法:

FileWriter(File file)給一個File對象構造一個FileWriter對象。
FileWriter(File file, boolean append)給一個File對象構造一個FileWriter對象。append爲true時則在文件末尾輸入
FileWriter(FileDescriptor fd)構造與文件描述符關聯的FileWriter對象。
FileWriter(String fileName)構造一個給定文件名的FileWriter對象。
FileWriter(String fileName, boolean append)構造一個FileWriter對象,給出一個帶有布爾值的文件名,表示是否附加寫入的數據。

構造方法的做用:
1.建立一個FileWriter對象
2.會根據構造方法中傳遞的文件路徑,建立文件
3.將FileWriter指向建立好的文件

字符流的使用:---字符和字節輸入流的區別在於,字符不是直接寫入文件,而是先寫入內存緩衝區
1.建立FileWriter對象,在構造方法中綁定要寫入的數據目的地
2.使用 FileWriter中的write()方法,把數據寫入內存緩衝區(在這一步,其實會將字符轉換爲字節由於計算機只認識字節)
3.使用FileWriter中的flush()方法將內存緩衝區的數據,刷新到文件中
4.釋放資源(在釋放資源時,會自動把內存緩衝區的數據刷新到文件)

public static void main( String[] args ) throws IOException {
        //建立輸出流對象
        FileWriter fw = new FileWriter("./src/JavaCore/IO/FOS.txt", true);
        //建立輸入流對象
        FileReader fr = new FileReader("./src/JavaCore/IO/FIS.txt");

        //讀取輸入流並輸出到輸出流
        char[] cs = new char[1024];
        int len;
        while ((len = fr.read(cs)) != -1) {

            fw.write(new String(cs, 0, len));
            //這裏要刷新流,否則字符輸出流不會寫入文件,而是留在內存緩衝區中
            fw.flush();
        }

        //關閉流,先關閉輸出流,再關閉輸入流,由於輸出流要依賴輸入流,因此要後關閉輸入流
        fw.close();
        fr.close();
    }

轉換流

從字節流到字符流的轉化,在字符流FileReader中的構造方法中仍然是繼承了字節流
public FileReader(String fileName) throws FileNotFoundException {    super(new FileInputStream(fileName)); }

InputStreamReader

java.lang.Object java.io.Reader java.io.InputStreamReader

InputStreamReader是從字節流到字符流的橋樑:它讀取字節,並使用指定的charset將其解碼爲字符 。 它使用的字符集能夠由名稱指定,也能夠被明確指定,或者能夠接受平臺的默認字符集。
每一個調用InputStreamReader的read()方法之一可能會致使從底層字節輸入流讀取一個或多個字節。 爲了使字節有效地轉換爲字符,能夠從底層流讀取比知足當前讀取操做所需的更多字節。
爲了最大的效率,請考慮在BufferedReader中包裝一個InputStreamReader。 例如: BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

構造方法:

InputStreamReader(InputStream in)建立一個使用默認字符集的InputStreamReader。
InputStreamReader(InputStream in, Charset cs)建立一個使用給定字符集的InputStreamReader。
InputStreamReader(InputStream in, CharsetDecoder dec)建立一個使用給定字符集解碼器的InputStreamReader。
InputStreamReader(InputStream in, String charsetName)建立一個使用命名字符集的InputStreamReader。

對象方法:和Reader一致

OutputStreamWriter

public class OutputStreamWriter extends WriterOutputStreamWriter是字符的橋樑流以字節流:向其寫入的字符編碼成使用指定的字節charset 。
使用的字符集能夠由名稱指定,也能夠被明確指定,或者能夠接受平臺的默認字符集。每次調用write()方法都會使編碼轉換器在給定字符上被調用。 所獲得的字節在寫入底層輸出流以前累積在緩衝區中。 能夠指定此緩衝區的大小,可是默認狀況下它大部分用於大多數目的。 請注意,傳遞給write()方法的字符不會緩衝。
爲了最大的效率,請考慮在BufferedWriter中包裝一個OutputStreamWriter,以免頻繁的轉換器調用。 例如: Writer out = new BufferedWriter(new OutputStreamWriter(System.out));

構造方法:

OutputStreamWriter(OutputStream out)建立一個使用默認字符編碼的OutputStreamWriter。
OutputStreamWriter(OutputStream out, Charset cs)建立一個使用給定字符集的OutputStreamWriter。
OutputStreamWriter(OutputStream out, CharsetEncoder enc)建立一個使用給定字符集編碼器的OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName)建立一個使用命名字符集的OutputStreamWriter。

對象方法:和Writer一致

本博客爲Swagger-Ranger的筆記分享,文章會持續更新 文中源碼地址: https://github.com/Swagger-Ranger 歡迎交流指正,若有侵權請聯繫做者確認刪除: liufei32@outlook.com

相關文章
相關標籤/搜索