字節(jié)流和字符流

File類雖然可以操作文件,但是并不是操作文件的內(nèi)容,如果要進(jìn)行內(nèi)容的操作只能通過(guò)兩種途徑:字節(jié)流、字符流

如果要進(jìn)行輸入,輸出操作一般都會(huì)按照如下的步驟(以文件操作為例):

  • 通過(guò)File類定義一個(gè)要操作文件的路徑;
  • 通過(guò)字節(jié)流或字符流的子類對(duì)象為父類對(duì)象實(shí)例化;
  • 進(jìn)行數(shù)據(jù)的讀(輸入)、寫(輸出)操作;
  • 數(shù)據(jù)流屬于資源操作,資源操作必須關(guān)閉。

java.io包定義了兩類流:

  • 字節(jié)流(JDK 1.0) : InputStream、OutputStream;
  • 字符流(JDK 1.1) : Reader、Writer。

1 字節(jié)輸出流:OutputStream(重點(diǎn))

OutputStream類是一個(gè)專門進(jìn)行字節(jié)數(shù)據(jù)輸出的一個(gè)類,定義如下:

public abstract class OutputStream
extends Object
implements Closeable, Flushable

可以發(fā)先OutputStream類實(shí)現(xiàn)了個(gè)兩個(gè)接口:Closeable, Flushable;這兩個(gè)接口定義如下:

Closeable接口(JDK 1.5) Flushable接口(JDK 1.5)
public interface Closeable extends AutoCloseable public interface Flushable

在JDK 1.7 中引入了自動(dòng)關(guān)閉機(jī)制,所以Closeable又繼承AutoCloseable接口,定義如下:

public interface AutoCloseable {
    public void close() throws Exception;
}

但是OutputStream類在JDK 1.0的時(shí)候就提供了,這個(gè)類原本就定義了close()和flush()兩個(gè)方法,所以現(xiàn)在以上的兩個(gè)接口就幾乎可以忽略。
在OutputStream類里面提供有三個(gè)輸出的方法:

  • 輸出單個(gè)字節(jié):public abstract void write(int b) throws IOException
  • 輸出全部字節(jié)數(shù)組:public void write(byte[] b) throws IOException
  • 輸出部分字節(jié)數(shù)據(jù)public void write(byte[] b, int off, int len) throws IOException
    OutputStream是抽象類,如果為抽象類進(jìn)行實(shí)例化操作,那么必須使用抽象類的子類,由于要使用文件操作,可以使用FileOutputStream子類,這個(gè)子類里面定義如下的構(gòu)造方法:
  • 創(chuàng)建或覆蓋已有文件:public FileOutputStream(File file) throws FileNotFoundException
  • 文件內(nèi)容追加:public FileOutputStream(File file, boolean append) throws FileNotFoundException

范例:文件內(nèi)容的輸出

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class IntOrOutPutStream {
    public static void main(String[] args) throws Exception {
        File file = new File("D:" + File.separator + "Document" + File.separator + "test.txt");
        if (!file.getParentFile().exists()) {
            file.mkdirs();
        }
        
        OutputStream output = new FileOutputStream(file);
        
        String str = "好好學(xué)習(xí),天天向上!";
        byte[] data = str.getBytes();
        output.write(data);
        output.close();
    }
}

以上是整個(gè)字節(jié)數(shù)組的內(nèi)容進(jìn)行了輸出,如果此時(shí)要輸出的文件不存在,就會(huì)自動(dòng)創(chuàng)建文件。
范例:單個(gè)字節(jié)的方式輸出

        for (int x = 0 ; x < data.length ; x++) {
            output.write(data[x]);
        }

范例:輸出部分字節(jié)數(shù)組內(nèi)容

output.write(data, 6, 4);

以上都是直接覆蓋原有文件內(nèi)容,也可以實(shí)現(xiàn)內(nèi)容的追加,只需要更換FileOutputStream類的構(gòu)造方法即可:

OutputStream output = new FileOutputStream(file , true);
//  \r\n 可以實(shí)現(xiàn)換行
String str = "好好學(xué)習(xí),天天向上!\r\n";

2 字節(jié)輸入流:InputStream

如果需要進(jìn)行數(shù)據(jù)的讀取操作,可以利用InputStream類實(shí)現(xiàn)功能,此類定義:public abstract class InputStream extends Object implements Closeable
雖然此類實(shí)現(xiàn)了Closeable接口,但是與OutputStream類一樣,可以不用考慮接口的存在,在InputStream類里面也定義又?jǐn)?shù)據(jù)讀取的方法:

  • 讀取單個(gè)字節(jié):public abstract int read() throws IOException
    · 返回值:返回讀取的字節(jié)內(nèi)容,如果結(jié)尾沒(méi)有數(shù)據(jù)了,返回 -1
  • 將讀取的數(shù)據(jù)保存在里字節(jié)數(shù)組里:public int read(byte[] b) throws IOException
    · 返回值:返回讀取的數(shù)據(jù)長(zhǎng)度,如果已經(jīng)讀取到結(jié)尾,返回 -1
  • 將讀取的數(shù)據(jù)保存在部分字節(jié)數(shù)據(jù)里:public int read(byte[] b, int off, int len) throws IOException
    · 返回值:讀取的部分?jǐn)?shù)據(jù)的長(zhǎng)度,如果已經(jīng)讀取到結(jié)尾,返回 -1

InputStream是一個(gè)抽象類,如果要進(jìn)行文件讀取使用子類FileInputStream,此子類的構(gòu)造方法:public FileInputStream(File file) throws FileNotFoundException
范例:向數(shù)組里面讀取數(shù)據(jù)

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class InputStreamTest {
    public static void main(String[] args) throws Exception{
        //1.定義要輸入的文件路徑
        File file = new File("D:" + File.separator + "Document" + File.separator + "test.txt");
        if (file.getParentFile().exists()) {
            //2. 使用InputStream進(jìn)行讀取
            InputStream input = new FileInputStream(file);
            //3. 讀取數(shù)據(jù)
            byte[] data = new byte[1024];   //準(zhǔn)備長(zhǎng)度為1024的數(shù)組
            int len = input.read(data);     //將內(nèi)容保存到字節(jié)數(shù)組中
            //4. 關(guān)閉輸入流
            input.close();
            System.out.println("{" + new String(data , 0 ,len) + "}");
        }
        
    }
}

范例:單個(gè)字節(jié)數(shù)據(jù)讀取

  • 文件有很多字節(jié)數(shù)據(jù),所以讀取數(shù)據(jù)應(yīng)采用循環(huán)的方式,但由于不確定循環(huán)次數(shù),所以使用while循環(huán)。
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;

public class InputStreamWhileTest {
    public static void main(String[] args) throws Exception {
        File file = new File("D:" + File.separator + "Document" + File.separator + "test.txt");
        if (file.getParentFile().exists()) {
            InputStream input = new FileInputStream(file);
            byte[] data = new byte[1024];
            int temp = 0;
            int foot = 0;
            //temp = input.read() , 表示將read() 方法讀取的字節(jié)內(nèi)容賦值給temp變量
            //(temp = input.read()) != -1 , 判斷讀取temp的內(nèi)容是否是-1
            while ((temp = input.read()) != -1) {
                data[foot++] = (byte) temp;     //有內(nèi)容進(jìn)行保存
            }
            input.close();
            System.out.println("{" +new String(data , 0 , foot)+ "}");
        }
    }
}

3 字符輸出流:Writer

Writer類是在JDK1.1之后增加的,其類的定義如下:
public abstract class Writer extends Object implements Appendable, Closeable, Flushable
這個(gè)類除了實(shí)現(xiàn)了Closeable與Flushable接口外,又多實(shí)現(xiàn)了一個(gè)Appendable,這個(gè)接口的定義如下:

public interface Appendable {
  public Appendable append(char c) throws IOException {}
  public Appendable append(CharSequence csq) throws IOException {}
  public Appendable append(CharSequence csq, int start, int end) throws IOException {}
}

在Appendable接口里面定義了追加類的操作,而且追加的數(shù)據(jù)都是字符或者字符串。
在Writer類里面定義有一下的輸出方法(部分):

  • 輸出全部字符數(shù)組:public void write(char[] cbuf) throws IOException
  • 輸出字符串:public void write(String str) throws IOException
    Writer是一個(gè)抽象類,如果想要為這個(gè)類的對(duì)象實(shí)例化,應(yīng)該使用FileWriter子類:
    范例:使用Writer類實(shí)現(xiàn)內(nèi)容輸出
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

public class WriterTest {
    public static void main(String[] args) throws Exception {
        File file = new File("D:" + File.separator + "Document" 
                + File.separator + "Document" + File.separator + "test.txt");
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        
        Writer writerfile = new FileWriter(file);
        String str = "Hello world!";
        writerfile.write(str);
        writerfile.close();
    }
}

4 字符輸入流:Reader

Reader 是進(jìn)行字符數(shù)據(jù)讀取的輸入流,其本身也是一個(gè)抽象類:
public abstract class Reader extends Object implements Readable, Closeable
在Reader類里面也提供有一系列的read()方法:

  • 讀取內(nèi)容到字符數(shù)組:public int read(char[] cbuf) throws IOException
    · 返回值:表示讀取的數(shù)據(jù)長(zhǎng)度,如果已經(jīng)讀取到結(jié)尾了,返回 -1;
    為Reader類實(shí)例化的可以使用FileReader子類完成。
    范例:使用Reader讀取數(shù)據(jù)
import java.io.File;
import java.io.FileReader;
import java.io.Reader;

public class ReaderTest {
    public static void main(String[] args) throws Exception {
        File file = new File(
                "D:" + File.separator + "Document" + File.separator + "Document" + File.separator + "test.txt");
        if (file.getParentFile().exists()) {
            Reader readerfile = new FileReader(file);
            char[] data = new char[1024];
            int len = readerfile.read(data);
            readerfile.close();
            System.out.println(new String(data, 0, len));
        }
    }
}

5 字節(jié)流與字符流的區(qū)別?

  1. 字節(jié)流直接與終端進(jìn)行數(shù)據(jù)交互,字符流需要將數(shù)據(jù)經(jīng)過(guò)緩沖去處理后才可以輸出。
  2. 在使用OutputStream輸出數(shù)據(jù)的時(shí)候,即使最后沒(méi)有關(guān)閉輸出流,內(nèi)容也可以正常輸出,但是不關(guān)閉字符輸出流,就表示在緩沖區(qū)中處理的內(nèi)容不會(huì)被強(qiáng)制性清空,所以就不會(huì)輸出數(shù)據(jù);如果有特殊情況不能夠關(guān)閉字符輸出流,可以使用flush()方法強(qiáng)制清空緩沖區(qū)。
    范例:強(qiáng)制清空緩沖區(qū)
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

public class FlushTest {
    public static void main(String[] args) throws Exception{
        File file = new File("D:" + File.separator + "Document" + File.separator + "Document" + File.separator + "test.txt");
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        Writer out = new FileWriter(file);
        String str = "Hello world @!";
        out.write(str);
        out.flush();
    }
}

在開發(fā)之中,對(duì)字節(jié)數(shù)據(jù)處理是比較多的,例如:圖片、音樂(lè)、電影;而對(duì)字符流最大的好處就是可以處理中文,所以在日后的開發(fā)之中,如果要處理中文, 優(yōu)先考慮字符流,沒(méi)有中文時(shí),建議使用字節(jié)流。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,610評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,668評(píng)論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,426評(píng)論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,656評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,833評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,371評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,621評(píng)論 2 380

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