黄色一级毛片网站_日韩在线国产_国产一级a在线观看_亚洲综合一区在线_99av视频_久久久7

當(dāng)前位置:首頁(yè) > 學(xué)習(xí)資源 > 講師博文 > Java字節(jié)流使用方法

Java字節(jié)流使用方法 時(shí)間:2018-03-01      來(lái)源:未知

在java中我們使用輸入流來(lái)向一個(gè)字節(jié)序列對(duì)象中寫入,使用輸出流來(lái)向輸出其內(nèi)容。C語(yǔ)言中只使用一個(gè)File包處理一切文件操作,而在java中卻有著60多種流類型,構(gòu)成了整個(gè)流家族。看似龐大的體系結(jié)構(gòu),其實(shí)只要使用適合的方法將其分門別類,就顯得清晰明了了。而我準(zhǔn)備將其按照處理文件類型的不同,分為字節(jié)流類型和字符流類型。

基類流

其實(shí)始終有人搞不清楚到底InputStream是讀還是OutputStream是讀。其實(shí)很簡(jiǎn)單就可以記住,你把你自己想象為是一個(gè)程序,InputStream對(duì)你來(lái)說(shuō)是輸入,也就是你要從某個(gè)地方讀到自己這來(lái),而OutputStream對(duì)你來(lái)說(shuō)就是輸出,也就是說(shuō)你需要寫到某個(gè)地方。這樣就可以簡(jiǎn)單的區(qū)分輸入輸出流。InputStream是一個(gè)輸入流,也就是用來(lái)讀取文件的流,抽象方法read讀取下一個(gè)字節(jié),當(dāng)讀取到文件的末尾時(shí)候返回 -1。如果流中沒(méi)有數(shù)據(jù)read就會(huì)阻塞直至數(shù)據(jù)到來(lái)或者異常出現(xiàn)或者流關(guān)閉。這是一個(gè)受查異常,具體的調(diào)用者必須處理異常。除了一次讀取一個(gè)字節(jié),InputStream中還提供了read(byte[]),讀取多個(gè)字節(jié)。read(byte[])其實(shí)默認(rèn)調(diào)用的還是read(byte b[], int off, int len)方法,表示每讀取一個(gè)字節(jié)就放在b[off++]中,總共讀取len個(gè)字節(jié),但是往往會(huì)出現(xiàn)流中字節(jié)數(shù)小于len,所以返回的是實(shí)際讀取到的字節(jié)數(shù)。

接下來(lái)是一些高級(jí)的用法,skip方法表示跳過(guò)指定的字節(jié)數(shù),來(lái)讀取。調(diào)用這種方法需要知道,一旦跳過(guò)就不能返回到原來(lái)的位置。當(dāng)然,我們可以看到還有剩下的三種方法,他們一起合作實(shí)現(xiàn)了可重復(fù)讀的操作。mark方法在指定的位置打上標(biāo)記,reset方法可以重新回到之前的標(biāo)記索引處。但是我們可以想到,它一定是在打下mark標(biāo)記的地方,使用字節(jié)數(shù)組記錄下接下來(lái)的路徑上的所有字節(jié)數(shù)據(jù),直到你使用了reset方法,取出字節(jié)數(shù)組中的數(shù)據(jù)供你讀取(實(shí)際上也不是一種能夠重復(fù)讀,只是用字節(jié)數(shù)組記錄下這一路上的數(shù)據(jù)而已,等到你想要回去的時(shí)候?qū)⒆止?jié)數(shù)組給你重新讀取)。

OutputStream是一種輸出流,具體的方法和InputStream差不多,只是,一個(gè)讀一個(gè)寫。但是,他們都是抽象類,想要實(shí)現(xiàn)具體的功能還是需要依賴他們的子類來(lái)實(shí)現(xiàn),例如:FileInputStream/FileOutputStream等。

Java字節(jié)流

文件字節(jié)流

FileInputStream繼承與InputStream,主要有以下兩個(gè)構(gòu)造方法:

public FileInputStream(String name)

public FileInputStream(File file)

第一種構(gòu)造方法傳的是一個(gè)字符串,實(shí)際上是一個(gè)確定文件的路徑,內(nèi)部將此路徑封裝成File類型,調(diào)用第二種構(gòu)造方法。第二中構(gòu)造方法,直接綁定的是一個(gè)具體的文件。FileInputStream 的內(nèi)部方法其實(shí)和父類InputStream中定義的方法差不多,我們通過(guò)一個(gè)讀文件的實(shí)例來(lái)演示用法。

FileInputStream fin = new FileInputStream("hello.txt");

byte[] buffer = new byte[1024];

int x = fin.read(buffer,0,buffer.length);

String str = new String(buffer);

System.out.println(str);

System.out.println(x);

fin.close();

結(jié)果意料之中,調(diào)用了read方法將hello.txt中的內(nèi)容讀到字節(jié)數(shù)組buffer中,然后通過(guò)String類構(gòu)造方法將字節(jié)數(shù)組轉(zhuǎn)換成字符串。返回實(shí)際上讀取到的字節(jié)數(shù)13。(10個(gè)字母+兩個(gè)空格+一個(gè)字符串結(jié)束符)FileOutputStream繼承父類OutputStream,主要方法代碼如下:

private final boolean append;

public FileOutputStream(String name)

public FileOutputStream(String name, boolean append)

public FileOutputStream(File file)

public FileOutputStream(File file, boolean append)

private native void writeBytes(byte b[], int off, int len, boolean append)

public void write(byte b[]) throws IOException

FileOutputStream的一些基本的操作和FileInputStream類似,只是一個(gè)是讀一個(gè)是寫。我們主要要知道,append屬性是指定對(duì)于文件的操作是覆蓋方式(false),還是追加方式(true)。下面通過(guò)一個(gè)實(shí)例演示其用法:

FileOutputStream fou = new FileOutputStream("hello.txt");

String str = "Walker_YAM";

byte[] buffer = str.getBytes("UTF-8");

fou.write(buffer,0 ,buffer.length);

fou.close();

如我們所料,字符串"Walker_YAM"將會(huì)被寫入hello.txt,由于沒(méi)有指定append,所以將會(huì)覆蓋hello.txt中的所有內(nèi)容。

動(dòng)態(tài)字節(jié)數(shù)組流

在我們上述的文件讀取流中,我們定義 byte[] buffer = new byte[1024];,buffer數(shù)組為1024,如果我們將要讀取的文件中的內(nèi)容有1025個(gè)字節(jié),buffer是不是裝不下?當(dāng)然我們也可以定義更大的數(shù)組容量,但是從內(nèi)存的使用效率上,這是低效的。我們可以使用動(dòng)態(tài)的字節(jié)數(shù)組流來(lái)提高效率。

ByteArrayInputStream的內(nèi)部使用了類似于ArrayList的動(dòng)態(tài)數(shù)組擴(kuò)容的思想。

protected byte buf[];

protected int count;

public ByteArrayInputStream(byte buf[])

public ByteArrayInputStream(byte buf[], int offset, int length)

public synchronized int read()

public synchronized int read(byte b[], int off, int len)

ByteArrayInputStream內(nèi)部定義了一個(gè)buf數(shù)組和記錄數(shù)組中實(shí)際的字節(jié)數(shù),read方法也很簡(jiǎn)單,讀取下一個(gè)字節(jié),read(byte b[], int off, int len) 將內(nèi)置字節(jié)數(shù)組讀入目標(biāo)數(shù)組。實(shí)際上,整個(gè)ByteArrayInputStream也就是將一個(gè)字節(jié)數(shù)組封裝在其內(nèi)部。為什么這么做?主要還是為了方便參與整個(gè)InputStream的體系,復(fù)用代碼。ByteArrayOutputStream的作用要比ByteArrayInputStream更加的實(shí)際一點(diǎn):

protected byte buf[];

protected int count;

public ByteArrayOutputStream() { this(32); }

public ByteArrayOutputStream(int size)

private void ensureCapacity(int minCapacity)

public synchronized void write(byte b[], int off, int len)

public synchronized void writeTo(OutputStream out)

public synchronized byte toByteArray()[]

public synchronized String toString()

和ByteArrayInputStream一樣,內(nèi)部依然封裝了字節(jié)數(shù)組buf和實(shí)際容量count,通過(guò)構(gòu)造方法可以指定內(nèi)置字節(jié)數(shù)組的長(zhǎng)度。主要的是write方法,將外部傳入的字節(jié)數(shù)組寫到內(nèi)置數(shù)組中,writeTo方法可以理解為將自己內(nèi)置的數(shù)組交給OutputStream 的其他子類使用。toByteArray和toString則會(huì)將內(nèi)置數(shù)組轉(zhuǎn)換成指定類型返回。下面我們利用他們解決剛開始說(shuō)的效率問(wèn)題。

FileInputStream fin = new FileInputStream("hello.txt");

ByteArrayOutputStream bou = new ByteArrayOutputStream();

int x = 0;

while((x = fin.read()) !=-1){

bou.write(x);

}

System.out.println(bou.toString());

從hello文件中每讀取一個(gè)字節(jié)寫入ByteArrayOutputStream 中,我們不用擔(dān)心hello文件太大而需要設(shè)置較大的數(shù)組,使用ByteArrayOutputStream 動(dòng)態(tài)增加容量,如果添加字節(jié)即將超過(guò)容量上限,進(jìn)行擴(kuò)充(往往是指數(shù)級(jí)擴(kuò)充)

裝飾者字節(jié)流

上述的流都是直接通過(guò)操作字節(jié)數(shù)組來(lái)實(shí)現(xiàn)輸入輸出的,那如果我們想要輸入一個(gè)字符串類型或者int型或者double類型,那還需要調(diào)用各自的轉(zhuǎn)字節(jié)數(shù)組的方法,然后將字節(jié)數(shù)組輸入到流中。我們可以使用裝飾流,幫我們完成轉(zhuǎn)換的操作。我們先看DataOutputStream。

public DataOutputStream(OutputStream out)

public synchronized void write(byte b[], int off, int len)

public final void writeBoolean(boolean v)

public final void writeByte(int v)

public final void writeShort(int v)

public final void writeInt(int v)

public final void writeDouble(double v)

簡(jiǎn)單的列舉了一些方法,可以看到,DataOutputStream只有一個(gè)構(gòu)造方法,必須傳入一個(gè)OutputStream類型參數(shù)。(其實(shí)它的內(nèi)部還是圍繞著OutputStream,只是在它的基礎(chǔ)上做了些封裝)。我們看到,有writeBoolean、writeByte、writeShort、writeDouble等方法。他們內(nèi)部都是將傳入的 boolean,Byte,short,double類型變量轉(zhuǎn)換為了字節(jié)數(shù)組,然后調(diào)用從構(gòu)造方法中接入的OutputStream參數(shù)的write方法。

緩沖流

在這之前,我們讀取一個(gè)字節(jié)就要將它寫會(huì)磁盤,這樣來(lái)回開銷很大,我們可以使用緩沖區(qū)來(lái)提高效率,在緩沖區(qū)滿的時(shí)候,或者流關(guān)閉時(shí)候,將緩沖區(qū)中所有的內(nèi)容全部寫會(huì)磁盤。BufferedInputStream和BufferedOutputStream也是一對(duì)裝飾流,我們先看看BufferedInputStream:

private static int DEFAULT_BUFFER_SIZE = 8192;

protected volatile byte buf[];

protected int pos;

protected int count;

public BufferedInputStream(InputStream in)

public BufferedInputStream(InputStream in, int size)

public synchronized int read()

public synchronized void mark(int readlimit)

public synchronized void reset()

一樣也是裝飾類流,第一種構(gòu)造方法要求必須傳入InputStream類型參數(shù),DEFAULT_BUFFER_SIZE 指定了默認(rèn)的緩沖區(qū)的大小,當(dāng)然還可以使用第二種構(gòu)造方法指定緩沖區(qū)的大小(當(dāng)然不能超過(guò)上界),read方法讀取的時(shí)候會(huì)將數(shù)據(jù)讀入內(nèi)部的緩沖區(qū)中,當(dāng)然緩沖區(qū)也是可以動(dòng)態(tài)擴(kuò)容的。

BufferedInputStream bi = new BufferedInputStream(new FileInputStream("hello.txt"));

bi.read();

bi.read();

bi.read();

bi.read();

System.out.println(bi.available());

BufferedOutputStream和它是逆操作,不在贅述。這種緩沖字節(jié)流可以很大程度上提高我們的程序執(zhí)行的效率,所以一般在使用別的流的時(shí)候都會(huì)包裝上這層緩沖流。

上一篇:三層架構(gòu)實(shí)現(xiàn)Java Web案例

下一篇:java抽象類的作用

戳我查看嵌入式每月就業(yè)風(fēng)云榜

點(diǎn)我了解華清遠(yuǎn)見高校學(xué)霸學(xué)習(xí)秘籍

猜你關(guān)心企業(yè)是如何評(píng)價(jià)華清學(xué)員的

干貨分享
相關(guān)新聞
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2024 北京華清遠(yuǎn)見科技發(fā)展有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5京公海網(wǎng)安備11010802025203號(hào)

回到頂部

主站蜘蛛池模板: 久久99亚洲精品久久久久 | 天天看片天天AV免费观看 | 国产一区二区三区视频在线观看 | 日韩精品在线中文字幕 | 亚洲一区二区三区精品视频 | 日日草夜夜爽 | 91精品国产影音先锋大全 | 久久精品97| 久久久久国产成人精品亚洲午夜 | 国产鲁鲁视频在线观看 | 国产A一级毛片高清视频完整片 | 中文字幕.亚洲无码日 | 7788成人网站免费观看 | 国产91精选二区 | 18禁真人抽搐一进一出在线 | 欧美一区二区在线观看 | 国产一区二区三区精品久久久 | 日韩亚 | 99国产精品久久久久久久久久 | 一道本一区二区 | 国产成人精品午夜视频免费 | 国产欧美亚洲精品第三页 | 草草影院在线 | 亚洲最大一级无码av网站 | 日韩精品综合网 | 日韩激情中文字幕 | 一区二区三区不卡在线观看 | 精品国产欧美 | 精品无码中文视频在线观看 | 日韩精品一区二区三区中文 | 亚洲精品中文字幕在线 | 一a毛片 | 久久久成人免费一区二区 | a毛片免费 | 国产精品久久久久久久久久免费动 | 国产一二级片 | 丁香六月中文字幕 | 在线看高清中文字幕一区 | 8x福利第一导航 | 99国产高清| 国产精品久久久久av |