Java中的I/O流

谷歌I/O大會(huì),現(xiàn)在趕一下時(shí)髦,在這里說(shuō)一下Java的I/O流。
I/O流可以簡(jiǎn)單的理解input/output流,既是輸入輸出流。谷歌I/O大會(huì)也可以解釋為谷歌輸入/輸出大會(huì),哈哈!電腦不就是用來(lái)輸入輸出的工具嘛,這樣理解也沒(méi)問(wèn)題。
話歸正題,I/O流在java中是屬于基礎(chǔ)類,是很重要的一個(gè)工具,有了它,才能夠?qū)崿F(xiàn)信息之間的交互,即從本地向網(wǎng)絡(luò)發(fā)出請(qǐng)求,然后在網(wǎng)絡(luò)中傳回信息。
input和output是相對(duì)而言的,即我們擁有一個(gè)客戶端處理器,如果外部有信息要傳進(jìn)來(lái)處理,那邊是輸入流input,而當(dāng)我們有信息要輸出時(shí),那邊是輸出流output了。

I/O流解析

舉個(gè)栗子來(lái)說(shuō)吧,
例子1:我們?cè)谄匠J褂檬謾C(jī)上網(wǎng)的時(shí)候,從手機(jī)上點(diǎn)擊鏈接,這時(shí)向互聯(lián)網(wǎng)發(fā)出指令,這是就是輸出output。而當(dāng)互聯(lián)網(wǎng)返回頁(yè)面的時(shí)候,那么就是輸入流了。
例子2:當(dāng)我們下載文件的時(shí)候,互聯(lián)網(wǎng)源源不斷的將文件內(nèi)容傳到手機(jī)上,這是輸入流input。但同時(shí)傳到手機(jī)上時(shí)只是一個(gè)緩存,還需要在存儲(chǔ)卡中把內(nèi)容保存起來(lái),因此手機(jī)把文件信息保存到內(nèi)置存儲(chǔ)卡中時(shí)便是輸出流output了。
解釋完什么是I/O,現(xiàn)在我們開(kāi)始輸入/輸出流的使用吧。

I/O流的使用

我們?cè)谶@里主要講解Stream流、Reader和Writer這三種。

字節(jié)流

Java中的Stream流主要指InputStream流和OutputStream流。
其中InputStream流和OutputStream流是抽象類,但是它們各自有同名的子類InputStream流和OutputStream,沒(méi)錯(cuò),它們的名字是一樣的。
作為抽象類的InputStream有讀取字節(jié)流(byte)的read()方法,它可以讀取字節(jié)或者字節(jié)數(shù)組,其次是close()方法,每次使用InputStream流之后記得使用close()方法,這樣才不會(huì)占用系統(tǒng)資源。
相應(yīng)的OutputStream流著擁有wrire()和close()方法,效果同InputSream,只是它是將直接寫(xiě)出。
作為抽象類的InputStream流和OutputStream流,他們各自有許多個(gè)實(shí)現(xiàn)的之類
如InputStream的子類有:

AudioInputStream
, ByteArrayInputStream
, FileInputStream
, FilterInputStream
, InputStream
, ObjectInputStream
, PipedInputStream
, SequenceInputStream
, StringBufferInputStream

如OutputStream的子類有:

ByteArrayOutputStream
, FileOutputStream
, FilterOutputStream
, ObjectOutputStream
, OutputStream
, PipedOutputStream

其中有個(gè)子類FileInputStream流,這個(gè)子類是從電腦磁盤(pán)或者內(nèi)存卡中的文件直接讀取字節(jié),而和FileOutputStream流則直接輸出信息到文件的流。

fileInputStream.png
fileOutputSream.png

用法:這是復(fù)制文本文件的一個(gè)方法,src和dst分別指?jìng)魅牒蛡鞒龅奈谋疚募窂?/p>

public static void copyFile(File src, File dst) throws IOException {
    FileInputStream fis = new FileInputStream(src);
    FileOutputStream fos = new FileOutputStream(dst);
    int data = -1;
    // fis.read()如果已到達(dá)文件末尾,則返回 -1。
    while ((data = fis.read()) != -1) {
        fos.write(data);
    }
    fis.close();
    fos.close();
}

上面的方法雖然能達(dá)到目的,但是在實(shí)際使用的時(shí)候因?yàn)槿狈彺妫瑥?fù)制文件的時(shí)間過(guò)長(zhǎng)導(dǎo)致卡頓,因此可以使用緩存區(qū)來(lái)加速,可以將代碼修改為:

public static void copyFile(File src, File dst) throws IOException {
    FileInputStream fis = new FileInputStream(src);
    FileOutputStream fos = new FileOutputStream(dst);
    // 創(chuàng)建一個(gè)1M大小的緩沖區(qū),用來(lái)存放輸入流中的字節(jié)
    byte[] buf = new byte[1024 * 1024];
    // 用來(lái)保存實(shí)際讀到的字節(jié)數(shù)
    int len = 0;
    // fis.read(buf) 讀入緩沖區(qū)的字節(jié)總數(shù),如果因?yàn)橐呀?jīng)到達(dá)文件末尾而沒(méi)有更多的數(shù)據(jù),則返回 -1。
    while ((len = fis.read(buf)) != -1) {
        // fos.write(buf, 0, len) 將指定 byte 數(shù)組中從偏移量 0 開(kāi)始的 len 個(gè)字節(jié)寫(xiě)入此文件輸出流。
        fos.write(buf, 0, len);
    }
    fis.close();
    fos.close();
}

接下來(lái)就是ByteArrayInputStream流,它將字節(jié)數(shù)組當(dāng)作源的輸入流;ByteArrayOutputStream則是將字節(jié)數(shù)組當(dāng)作目標(biāo)的輸出流。值得注意的是這個(gè)輸入輸出流雖然都有一個(gè)close()方法,但是由于ByteArrayInputSteam/ByteArrayOutputStream并沒(méi)有調(diào)用系統(tǒng)資源,因此這個(gè)關(guān)閉方法沒(méi)有任何意義。
ByteArrayInputSteam使用示例:

public static void main(String[] args) throws IOException {
    String str = "hello,World";
    ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes());
    int data = -1;
    while ((data = bis.read()) != -1) {
        System.out.print((char) data);
    }
    bis.close();
}

ByteArrayOutputStream使用示例:

public static void main(String[] args) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    // 寫(xiě)入字節(jié),字符a在Unicode編碼表中是97,A是65
    bos.write(97);
    bos.write(65);
    bos.write("hello,world".getBytes());
    byte[] buff = bos.toByteArray();
    for (byte data : buff) {
        System.out.print((char) data);
    }
}

FilterInputStream/FilterOutputStream過(guò)濾流

FilterInputStream/FilterOutputStream過(guò)濾流,為底層透明的提供擴(kuò)展方法的輸入/輸出流的包裝。過(guò)濾流的構(gòu)造方法需要傳入一個(gè)參數(shù),F(xiàn)ilterInputStream流及其子類均需要傳入InputStream流,而FilterOutputStream流及其子類則需要傳入OutputStream流。

** FilterInputStream的子類有:**

BufferedInputStream,
CheckedInputStream,
CipherInputStream,
DataInputStream,
DeflaterInputStream,
DigestInputStream,
InflaterInputStream,
LineNumberInputStream,
ProgressMonitorInputStream,
PushbackInputStream

FilterOutputStream的子類有:

BufferedOutputStream,
CheckedOutputStream,
CipherOutputStream,
DataOutputStream,
DeflaterOutputStream,
DigestOutputStream,
InflaterOutputStream,
PrintStream

例如BufferedInputStream/BufferedOutputStream流,它們自帶一個(gè)緩沖區(qū),不必像上面copyFile()方法一般需要自定義一個(gè)byte數(shù)組來(lái)充當(dāng)緩沖區(qū),我們?cè)俅涡薷腸opyFile()方法,實(shí)現(xiàn)用過(guò)濾流復(fù)制文件。

public static void copyFile(File src, File dst) throws IOException {
    FileInputStream fis = new FileInputStream(src);
    FileOutputStream fos = new FileOutputStream(dst);
    // FileInputStream與FileOutputStream是InputStram和OutputStream的子類,
    // 因此能直接被BufferedInputStream與BufferedOutputStream讀取
    BufferedInputStream bis = new BufferedInputStream(fis);
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    // data用來(lái)保存實(shí)際讀到的字節(jié)數(shù)
    int data = 0;
    while ((data = bis.read()) != -1) {
        bos.write(data);
    }
    bis.close();
    bos.close();
}

但是對(duì)于上面的輸入輸出流仍然存在著一個(gè)問(wèn)題,那就是對(duì)于Java的基本數(shù)據(jù)類型的讀取,如int/double/boolean/char類型的讀取,因此引入了DataInputStream/DataOutputStream來(lái)處理。需要注意的是使用它們時(shí),讀取與寫(xiě)出的順序必須要一致。
DataInputStream使用示例:

public static void main(String[] args) throws IOException {
     String name = "zhangsan";
     int age = 10;
     boolean flag = true;
     char sex = '男';
     double money = 100.56;
     DataOutputStream dos = new DataOutputStream(new FileOutputStream("e:\\b.txt"));
     dos.writeUTF(name);
     dos.writeInt(age);
     dos.writeBoolean(flag);
     dos.writeChar(sex);
     dos.writeDouble(money);
     dos.close();
}

DataOutputStream使用示例(讀取上面使用DataInputStream寫(xiě)入的信息):

public static void main(String[] args) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream("e:\\b.txt"));
    // 讀的順序必須和寫(xiě)的順序一致
    System.out.println(dis.readUTF());
    System.out.println(dis.readInt());
    System.out.println(dis.readBoolean());
    System.out.println(dis.readChar());
    System.out.println(dis.readDouble());
    dis.close();
}

字符流

原本使用字節(jié)流已經(jīng)滿足了I/O的所有需求的,但是可惜的是計(jì)算機(jī)的編碼格式太多,如中國(guó)的GBK,還有ASCII/Unicode等編碼,不同的編碼之間并不兼容,如GBK是一個(gè)漢字有兩個(gè)字節(jié),而ASCII/Unicode則是一個(gè)字母一個(gè)字節(jié),如果用ANSI來(lái)解析GBK則會(huì)造成亂碼。這時(shí)字符流Reader類和Writer類就派上用場(chǎng)了,要注意的是,字符流雖然讀取的是char數(shù)組,但它們的底層還是依靠byte字節(jié)來(lái)讀取的。
由于Reader和Writer是抽象類,因此要靠子類來(lái)實(shí)現(xiàn)它們的抽象方法

Reader類的子類:

BufferedReader,
CharArrayReader,
FilterReader,
InputStreamReader,
PipedReader,
StringReader

Writer類的子類:

BufferedWriter,
CharArrayWriter,
FilterWriter,
OutputStreamWriter,
PipedWriter,
PrintWriter,
StringWriter

FilterReader/FilterWriter

FilterReader/FilterWriter對(duì)應(yīng)的是字節(jié)流中的FilterInputStream和FilterOutputStream對(duì)應(yīng),能夠直接對(duì)文件進(jìn)行操作,但是它是假定文件中的默認(rèn)編碼格式是電腦中的默認(rèn)編碼格式來(lái)讀取的,是InputStreamReader和OutputStreamWriter的子類
示例:

public static void main(String[] args) throws IOException {
    FileReader fr = new FileReader("e:\\c.txt");
    FileWriter fw = new FileWriter("e:\\d.txt");
    char[] buff = new char[100];
    int len = 0;// 實(shí)際讀到的字符個(gè)數(shù)
    while ((len = fr.read(buff)) != -1) {
        fw.write(buff, 0, len);
        // 當(dāng)FileWriter忘記關(guān)閉,而FileWriter緩存沒(méi)寫(xiě)滿時(shí),文件將寫(xiě)入失敗,
        // 這是應(yīng)該調(diào)用flush()方法,強(qiáng)制清空緩存,將信息寫(xiě)入文件中
        // fw.flush();
    }
    fr.close();
    // close()在使用的時(shí)候會(huì)強(qiáng)制調(diào)用flush(),強(qiáng)制清空緩存
    fw.close();
}

BuferedReader和BufferedWriter

通過(guò)緩沖輸入/輸出提高性能。這個(gè)方法所讀取得是字符輸入/輸出流,即InputStreamReader/OutputStreamWriter流,因?yàn)镽eader類和Writer類(如FileReader和FileWriter)會(huì)頻繁的調(diào)用底層資源,因此建議使用BufferedReader對(duì)其進(jìn)行包裝,如:BufferedReader in = new BufferedReader(new FileReader("foo.in"));
另外由于每個(gè)平臺(tái)如Linux和windows的換行符符號(hào)不同的,因此BufferedWriter中有newLine()方法來(lái)實(shí)現(xiàn)各的平臺(tái)統(tǒng)一換行。

BuferedReader和BufferedWriter示例:

public static void main(String[] args) throws IOException {
    FileReader fr = new FileReader("e:\\EclipseDemo1.java");
    BufferedReader br = new BufferedReader(fr);
    FileWriter fw = new FileWriter("e:\\aa.java");
    BufferedWriter bw = new BufferedWriter(fw);
    String line = null;
    // br.readLine()到達(dá)流的末尾時(shí)會(huì)返回null
    while ((line = br.readLine()) != null) {
        System.out.println(line);
        bw.write(line);
        bw.newLine();// 換行
        // flush()方法同F(xiàn)ileWriter
        // bw.flush();
    }
    br.close();
    bw.close();
}

轉(zhuǎn)換流InputStreamReader/OutputStreamWriter

轉(zhuǎn)換流能夠?qū)⒆止?jié)流和字符流相互轉(zhuǎn)換,如將InputStream流轉(zhuǎn)換為InputStreamReader字符流,用OutputStreamWriter轉(zhuǎn)換為OutputStream,需要傳入InputStream/OutputStream類的參數(shù)。
另外轉(zhuǎn)換流還有一個(gè)優(yōu)勢(shì),它能夠?qū)⒆x取指定編碼格式的文件信息,而FileReader只能夠讀取默認(rèn)編碼格式的文本文件。

OutputStringWriter示例:

public static void main(String[] args) throws IOException {
    FileOutputStream fos = new FileOutputStream("e:\\1.txt");
    OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
    BufferedWriter bw = new BufferedWriter(osw);
    bw.write("你好");
    bw.close();
}

InputStreamReader示例:

public static void main(String[] args) throws IOException {
    FileInputStream fis = new FileInputStream("e:\\1.txt");
    InputStreamReader isr = new InputStreamReader(fis, "utf-8");
    BufferedReader br = new BufferedReader(isr);
    String line = null;
    // br.readLine()到達(dá)流的末尾時(shí)會(huì)返回null
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
    br.close();
}

總結(jié)

對(duì)于JAVA中的I/O流就到這里結(jié)束了,I/O流中的類和方法都大同小異,相信只要掌握了本文所說(shuō)的這些類和方法,那么就能掌握絕大部分的I/O流操作了。
I/O流之中有一些共同的特性,它們可以直接在各自的抽象類中找到.
如:

  • 繼承自InputStream抽象類和Reader抽象類的子類中,它們都有read()方法,而且使用這個(gè)方法讀取到文件末尾時(shí)都是返回-1。
    (字符流中的BufferedReader有readLine()方法,它返回的是null值。相應(yīng)的BufferedWriter中有newLine()方法用來(lái)?yè)Q行,但沒(méi)有返回值)

最后以獲得網(wǎng)絡(luò)圖片作為JAVA中的I/O流的結(jié)束吧!

/**
 * 
 * @param urlString 下載網(wǎng)絡(luò)資源的地址,如圖片的下載地址
 * @param fileName  要把下載的資源的重命名
 * @param savePath  要下載資源保存到哪里
 * @throws Exception
 */
    public static void download (String urlString, String fileName,
            String savePath) throws IOException {
        URL url = new URL(urlString);
        URLConnection conn = url.openConnection();
        // 網(wǎng)絡(luò)連接超時(shí)的時(shí)間限制
        conn.setReadTimeout(5*1000);
        conn.setConnectTimeout(5*1000);
        // 獲取文件流
        InputStream is = conn.getInputStream();
        byte[] buff = new byte[1024];
        int len = 0;
        // 判斷下載保存的路徑是否存在,不存在則創(chuàng)建
        File file = new File(savePath);
        if(!file.exists()){
            file.mkdirs();
        }
        // 將獲取的流寫(xiě)入到電腦磁盤(pán)中
        OutputStream os = new FileOutputStream(file.getAbsolutePath() + "\\" + fileName);
        while((len = is.read(buff)) != -1 ) {
            os.write(buff, 0, len);
        }
        is.close();
        os.close();
    }

補(bǔ)充知識(shí)點(diǎn)

最近重新看了一下IO流的知識(shí),發(fā)現(xiàn)又有些迷糊,然后又仔細(xì)研究了一下。

關(guān)于字節(jié)流:

字節(jié)流也就是byte,按照字節(jié)讀取,也就是說(shuō)只要集成了InputStream的流對(duì)象都是字節(jié)流,都使用byte。
字節(jié)流的讀取方法一般用以下兩種:

read() :從此輸入流中讀取下一個(gè)數(shù)據(jù)字節(jié),每次會(huì)返回一個(gè)字節(jié)
這種時(shí)候,讀取和寫(xiě)入的方法如同上面的FileInputStream的操作一般,每讀取一個(gè)字節(jié)就寫(xiě)入一個(gè)字節(jié)。

第二種辦法就是使用數(shù)組緩沖區(qū)的方法read(byte[] b) ,它將會(huì)將讀取的數(shù)據(jù)保存在緩沖區(qū)中,也是像上面使用緩沖的FileInputStream的操作一般,然后使用OutputStream寫(xiě)入。

但是在實(shí)際操作中發(fā)現(xiàn)寫(xiě)入的過(guò)程中使用write(byte b[])和write(byte b[], int off, int len)(上文中的FileInputStream緩沖區(qū)寫(xiě)入)方法均可寫(xiě)入,代碼如下:

        File file1 = new File("D:\\a\\1.txt");
        File file2 = new File("D:\\a\\2.txt");
        FileInputStream fis = new FileInputStream(file1);
        FileOutputStream fos = new FileOutputStream(file2);
        // 創(chuàng)建一個(gè)1M大小的緩沖區(qū),用來(lái)存放輸入流中的字節(jié)
        byte[] buf = new byte[1024 * 1024];
        // fis.read(buf) 讀入緩沖區(qū)的字節(jié)總數(shù),如果因?yàn)橐呀?jīng)到達(dá)文件末尾而沒(méi)有更多的數(shù)據(jù),則返回 -1。
        while (fis.read(buf) != -1) {
            fos.write(buf);            
        }
        fis.close();
        fos.close();

這讓我不禁腦洞打開(kāi),或許只使用write(byte b[])方法便能夠完成操作,而不必調(diào)用傳入多個(gè)參數(shù)的方法呢?

但實(shí)際上這種方法并不可取,為什么呢?

在完成操作之后,仔細(xì)查看1.txt和2.txt的卻別,發(fā)現(xiàn)1.txt的文件大小之后1k,但是2.txt卻有1024k,打開(kāi)2.txt之后發(fā)現(xiàn)多出來(lái)的大小全部都是空格!
通過(guò)查看源碼我們得知:

public void write(byte b[]) throws IOException {
    writeBytes(b, 0, b.length, append);
    // 寫(xiě)入了整個(gè)緩沖區(qū)的大小,包括沒(méi)有內(nèi)容的部分
}

public void write(byte b[], int off, int len) throws IOException {
    writeBytes(b, off, len, append);
    // 按照實(shí)際的數(shù)組內(nèi)容長(zhǎng)度寫(xiě)入
}

這兩種方法同樣調(diào)用了writeBytes()方法,但是write(byte b[])它會(huì)將byte[]的大小設(shè)置為需要讀取的大小,也就是說(shuō)如果我們的緩沖區(qū)設(shè)置為1024*1024也就是1024k的大小,它就讀取1024k的大小,如果設(shè)置了1024m的大小也將同樣讀取1024M的大小,即使內(nèi)容的實(shí)際長(zhǎng)度并沒(méi)有這么多。
這邊是兩者之間的區(qū)別。

關(guān)于字符流

字符流也就是char,按照字符讀取,也就是說(shuō)只要集成了Reader的流對(duì)象都是字符流,都使用char。

如果字節(jié)流的讀寫(xiě)操作一樣,他們都有read()和writer()方法,區(qū)別只是將其中的byte換成char而已。

同樣寫(xiě)入方法有這兩種:

write(char[] cbuf) 
write(char[] cbuf, int off, int len) 

它們出現(xiàn)的問(wèn)題與字節(jié)流是一樣的。

因此我們寫(xiě)入文件操作的時(shí)候切記要設(shè)置好寫(xiě)入的長(zhǎng)度,否則寫(xiě)入空內(nèi)容不僅浪費(fèi)效率,還會(huì)導(dǎo)致保存的文件信息錯(cuò)誤而無(wú)法打開(kāi)。

由此明白了這些事情:

字節(jié)流設(shè)置了緩沖數(shù)組:

byte[] buf = new byte[1024 * 1024];

在InputStream讀取的過(guò)程中,會(huì)將內(nèi)容保存到buf中。

字符流設(shè)置緩沖數(shù)組:

char[] buff = new char[100];

在Reader的讀取過(guò)程中會(huì)將內(nèi)容保存到buff當(dāng)中。

但是在讀取過(guò)程中我們要設(shè)置當(dāng)前讀了多少,也就是設(shè)置:

int len = 0;// 實(shí)際讀到的字符個(gè)數(shù)
(len = fr.read(buff)) != -1

然后在通過(guò)write(char[]/byte[] cbuf, int off, int len) 保存相應(yīng)長(zhǎng)度的內(nèi)容。

流轉(zhuǎn)String

對(duì)于String字符串對(duì)象而已,也是一樣,

我們發(fā)現(xiàn)String的構(gòu)造方法中有char和byte的方法,如下:

String(byte[] bytes) // 通過(guò)使用平臺(tái)的默認(rèn)字符集解碼指定的 byte 數(shù)組,構(gòu)造一個(gè)新的 String。
String(byte[] bytes, int offset, int length) 
// 通過(guò)使用平臺(tái)的默認(rèn)字符集解碼指定的 byte 子數(shù)組,構(gòu)造一個(gè)新的 String。

String(char[] value)     // 分配一個(gè)新的 String,使其表示字符數(shù)組參數(shù)中當(dāng)前包含的字符序列。
String(char[] value, int offset, int count) 
// 分配一個(gè)新的 String,它包含取自字符數(shù)組參數(shù)一個(gè)子數(shù)組的字符。

但是與字節(jié)流和字符流一樣,都是參數(shù)少的會(huì)調(diào)用參數(shù)多的方法來(lái)創(chuàng)建String,因此在將流存為字符串的時(shí)候,也要遵守上面的規(guī)則,也就是說(shuō)要設(shè)置讀取了多長(zhǎng)的內(nèi)容。

字節(jié)流轉(zhuǎn)為String方法如下:

    File file1 = new File("D:\\a\\1.txt");
    FileReader fr = new FileReader(file1);
    // 創(chuàng)建一個(gè)1M大小的緩沖區(qū),用來(lái)存放輸入流中的字節(jié)
    char[] buf = new char[1024 * 1024];
    // 用來(lái)保存實(shí)際讀到的字節(jié)數(shù)
    int len = 0;
    // fis.read(buf) 讀入緩沖區(qū)的字節(jié)總數(shù),如果因?yàn)橐呀?jīng)到達(dá)文件末尾而沒(méi)有更多的數(shù)據(jù),則返回 -1。
    while ((len = fr.read(buf)) != -1) {
        System.out.println(new String(buf, 0, len));
    }
    fr.close();

字符流轉(zhuǎn)換方法如下:

    File file1 = new File("D:\\a\\1.txt");
    FileInputStream fis = new FileInputStream(file1);
    // 創(chuàng)建一個(gè)1M大小的緩沖區(qū),用來(lái)存放輸入流中的字節(jié)
    byte[] buf = new byte[1024 * 1024];
    // 用來(lái)保存實(shí)際讀到的字節(jié)數(shù)
    int len = 0;
    // fis.read(buf) 讀入緩沖區(qū)的字節(jié)總數(shù),如果因?yàn)橐呀?jīng)到達(dá)文件末尾而沒(méi)有更多的數(shù)據(jù),則返回 -1。
    while ((len = fis.read(buf)) != -1) {
        System.out.println(new String(buf, 0, len));
    }
    fis.close();

關(guān)于I/O流就到此結(jié)束了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Java 流在處理上分為字符流和字節(jié)流。字符流處理的單元為 2 個(gè)字節(jié)的 Unicode 字符,分別操作字符、字符...
    布魯斯不吐絲閱讀 703評(píng)論 0 4
  • 一、流的概念和作用。 流是一種有順序的,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偝苫虺橄蟆<磾?shù)據(jù)在兩設(shè)備之間的傳輸...
    布魯斯不吐絲閱讀 10,101評(píng)論 2 95
  • 摘要 Java I/O是Java技術(shù)體系中非常基礎(chǔ)的部分,它是學(xué)習(xí)Java NIO的基礎(chǔ)。而深入理解Java NI...
    biakia閱讀 7,646評(píng)論 7 81
  • 任何一個(gè)愛(ài)好,都是燒錢(qián)燒時(shí)間的,業(yè)余時(shí)間學(xué)習(xí)一個(gè)興趣愛(ài)好,確實(shí)蠻辛苦的。辛苦之一是沒(méi)有找到合適的學(xué)習(xí)方法,時(shí)間安排...
    可可慕莎Ada閱讀 262評(píng)論 0 2
  • 聲催鑼鼓,樂(lè)引爆竹。暖陽(yáng)千縷春意濃。千門(mén)萬(wàn)戶置新符,三杯兩盞品屠蘇。 歲寒漸隱,舊誼彌新。春來(lái)時(shí)節(jié)愈思親。寥寥數(shù)語(yǔ)...
    59a1ed7ac49b閱讀 163評(píng)論 0 0