亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java 網絡編程---I/O部分學習筆記整理1

2019-11-17 06:34:30
字體:
來源:轉載
供稿:網友

       網絡程序的很大一部分是簡單的輸入輸出,即從一個系統向另一個系統移動字節。字節就是字節,在很大程度上,讀服務器發送的數據與讀取文件沒什么不同;向客戶傳送數據與寫入一個文件也沒有什么區別。

       java中輸入和輸出組織不同于大多數其他語言。它是建立在流(stream)上。不同的基本流類(如java.io.FileInputStream和sun.net.TelnetOutputStream)用于讀寫特定的數據資源。但是所有的基本輸出流使用同一種基本方法讀數據。

       過濾器流可以連接到輸入流或輸出流。它可以修改已經讀出或寫人的數據(例如,加密或壓縮數據),或者可以簡單地提供附加方法將已經讀出或寫入的數據轉化成其他格式。

       最后Reader和Writer也可以鏈接到輸入流和輸出流,從而答應程序讀出和寫入文本(即字符)而不是字節。假如使用正確,Reader和Writer能夠處理多種類型的字符編碼,包括SJIS和UTF-8等多字節字符集。

 

一、輸出流

java的基本輸出流是 java.io.OutputStream.

public abstract class OutputStream

n         public abstract void write(int b) throws IOException

n         public void write(byte[] data) throws IOException

n         public void write(byte[] data,int offset,int length) throws IOException

n         public void flush() throws IOException

n         public void close() throws IOException

OutputStream的子類使用這些方法向指定媒體寫入數據。

 

我使用相信,我們理解了問什么它們存在,就會更好地記住它們,好,現在開始說一下OutputStream類的方法的由來

Ø         public abstract void write(int b) throws IOException

OutputStream的基本方法是write(int b)。該方法將介于0到255之間的整數看作變量,并將相應的字節寫到一個輸出流。該方法聲明是個抽象方法,因為子類需要改變它以處理特定媒體。例如,ByteArrayOutputStream可以使用拷貝字節到其數組的純Java代碼來實現方法。但是,FileOutputStream就需要使用代碼,此代碼應該理解如何在主機平臺上將數據寫入文件。注重:盡管該方法把整形值作為變量,但是它實際上寫入的是一個無符號字節。Java沒有無符號字節數據類型,因此這里使用整型來代替。無符號字節和有符號字節之間的真正區別是編譯器對它們的解釋。二者都是由8位組成,并且當使用write(int b)將一個int寫入到網絡連接流時,只有8位數據傳送。假如將一個超出0-255范圍的int傳給write(int b),則寫入該數字的低位字節,而忽略余下的三個字節(大家都知道java的int是4個字節的,這里本質就是將int轉換為byte)。

 

Ø         public void write(byte[] data) throws IOException和public void write(byte[] data,int offset,int length) throws IOException

每次寫入一個字節通常效率不高。因此,大部分TCP/ip程序將數據存入一定長度的緩沖區,即在內存中累積字節,并僅當累積了一定數目字節或過了一定的時間段,才將它們發送到最終的目的地。因此write(byte[] data)和write(byte[] data,int offset,int length)就是這樣產生了。

 

Ø         public void flush() throws IOException

我們可以在軟件中或直接在Java代碼中對流實施緩沖操作,也可以在網絡硬件中對流實施緩沖操作。就似乎BufferedOutputStream或BufferedWriter鏈接到底層流來實現流緩沖。因此,假如正在寫入數據,則刷新輸出流是相當重要的。例如,假設已經寫入了一個300字節的請求給一個HTTP Keep-Alive的HTTP服務器,通常希望在發送更多數據之間等待響應。但是,假如輸出流有一個1024字節的緩沖區,則該流可能在將數據發送出緩沖區之前正在等待更多的數據到達,但是這些數據似乎不會到達的,因為它們還沒有發送出去,但是緩沖流不會發送數據給服務器,除非它從底層流獲得更多的數據,但是底層流不會發送更多的數據,除非它從服務器獲得數據,而服務器不會發送數據,除非它獲得保留在緩沖區中的數據(死鎖了!),flush()方法就可以解決了這個僵局,因為即使緩沖區未滿,他也會強制要求實行緩沖操作的流傳送數據。注重:是否對流實行了緩沖操作,這決定于你如何獲得指向流的引用(例如,不論是否希望對System.out執行緩沖操作,都會對其實施緩沖)。假如刷新流需要刷新時,就必須刷新,但是假如刷新失敗了就會導致不可預料、不可重復的程序掛起(flush()返回值是void啊),假如事先不了解掛起問題所在,就很難解決這個問題了。因此,在關閉所有流之前,應當立即刷新它們。否則,關閉流前,緩沖區中的剩余數據可能會丟失。

 

Ø         public void close() throws IOException

最后當利用完流之后,應當調用close()方法關閉流。它會釋放所有與這個流相關的資源,如文件句柄或端口。一旦輸出流關閉了,再向其寫入數據就會觸發IOException異常。但是,有些類型可能答應對對象進行一定操作。如一個已關閉的ByteArrayOutputStream仍然可以轉化成一個實際的字節數組,而且一個已關閉的DigestOutputStream仍可以返回其摘要。

 

二、輸入流

java的基本輸入流是java.io.InputStream

public abstract class InputStream

n         public abstract int read() throws IOException

n         public int read(byte[] data) throws IOException

n         public int read(byte[] data,int offset,int length) throws IOException

n         public long skip(long n) throws IOException

n         public int available() throws IOException

n         public void close() throws IOException

InputStream的具體子類使用這些方法從指定媒體讀取數據。但是不論讀取何種資源,幾乎只能使用這六種方法。有時你甚至可能不知道正在從哪種類型的流中讀取數據。如隱藏在sun.net包中TelnetInputStream是一個文檔沒有說明的類。TelnetInputStream的實例由java.net包中的多種方法返回;如java.net.URL的openStram()方法。但是,這些方法僅聲明了返回InputStream,而不是更加明確的子類TelnetInputStream,這又是多態性在起作用了。子類的實例可以作為超類的實例透明使用。

來了,又來說明方法的由來了。

Ø         public abstract void read() throws IOException

InputStream類的基本方法是沒有參量的read()方法(這個與OutputStream不同了)。該方法從輸入流資源讀取一個單個字節數據并將數據作為0到255之間的數返回,返回-1時表示流的結尾。因為Java沒有無符號字節的數據類型,所以數據以整型類型返回。Read()方法等待和阻塞該方法后人和代碼的執行,直到獲得數據的一個字節并預備讀取該字節。因此,輸入和輸出可能相當慢,這時用戶假如需要完成其他比較重要的任務時,最好試圖將I/O放到它們自己的線程中。Read()方法被聲明為抽象方法,因為子類需要改變它來處理特定媒體。給個例子

byte[] input=new byte[10];

for(int i=0;i<input.length;i++){

       int b=in.read();

       if(b==-1) break;

       input[i]=(byte)b;

}

上面盡管read()方法僅讀取字節,但是它返回的是整型值。因此在將結果存儲到字節數組之前,需要一個類型轉換的過程。當然,這會產生一個介于-128到127的有符號字節,而不是read()方法返回的0到255之間的一個無符號字節。但是,只要用戶清楚使用的是無符號還是有符號字節就不會有很大問題。因此,我們可以把一個有符號字節轉化成無符號字節(轉換的原因是只有范圍在0-255的整數才可以被存儲在java的一個byte類型的變量中)。

int i=b>=0?b:256+b;

這里費了大篇幅,說明了read()返回的與java的byte類型的處理問題,大家可要注重阿,假如對java的原始數據類型還有愛好,可以看一下我的原始數據類型學習筆記(未完成)。

 

Ø         public int read(byte[] data) throws IOException、public int read(byte[] data,int offset,int length) throws IOException

每次讀取一個字節和每次寫入一個字節效率都不高,因此read(byte[] data)和read(byte[] data,int offset,int length)也相應產生了。這兩個方法將從流中讀取的多個字節填充到一個指定的數組中。注重:這些填充到數組的操作不一定會成功的。一個很普遍的情況是一個讀試圖不會完全失敗也不會完全成功,它可能讀出請求數據的一部分字節,而不是全部字節。例如,當實際上只有512字節已經到達服務器時,用戶可能會試圖從一個網絡流上讀取1024字節,而其他字節仍然在傳送中,這些字節最終會到達服務器,但到達時卻已是不可以獲得的。因此,多字節讀取方法會返回實際讀取的字節數目。給個例子

byte[] input=new byte[1024];

int bytesRead=in.read(input);

代碼段試圖從InputStream in讀取1024字節到數組input中。但是,假如僅有512字節可以獲得,則這些字節就是將要讀取的全部字節,并且bytesRead值會設為512。但我們為了保證在實際上讀取到所有的字節,怎么辦?看

int bytesRead=0;

int byteToRead=1024;

byte[] input=new byte[byteToRead];

while(bytesRead<byteToRead){

       bytesRead+=in.read(input,bytesRead,byteToRead-bytesRead);

}

Ø         public int available() throws IOException

假如由于某種原因用戶不希望讀取數據,除非用戶想要的全部數據可以立即得到,這時候就可以用available()方法返回的字節數是能夠讀取的最小字節數,而在實際上可以讀取更多的字節,但是能夠讀取的字節數據至少與available()返回的字節數一樣多。

看例子

int bytesAvailable=in.available();

byte[] input=new byte[bytesAvailable];

int byteTead=in.read(input,0,bytesAvailable);

//其他代碼

這里我們可以斷言bytesRead正好等于bytesAvailable,但不能斷言bytesRead>0,因為available()返回0是有可能的。

流結束時:

available()返回0;

read(byte[] data,int offset,int length)通常返回-1;

       流沒有結束,可讀取字節數即available()得到的值為0時

read(byte[] data,int offset,int length)會忽略流的結束,返回0;

 

Ø         public long skip(long n) throws IOException

在極少數情況下,用戶可能希望跳過數據而不去讀取它們。Skip()方法就是實現這個功能的。這個方法在從文件讀取數據時較為有用,而在網絡連接流上則用處較小。因為網絡連接流是有序的而且通常很慢,因此讀取數據的耗時不會太多的超過跳過數據的耗時。文件可以隨機訪問,因此我們通過重定位文件指針就能簡單的實現數據的跳轉,而不是跳過每一個字節。

 

Ø         public void close() throws IOException

和輸出流一樣,程序利用完輸入流之后,就應該調用close()方法關閉該輸入流了(要記住啊)。該方法會釋放與輸入流有關的所有資源,如文件句柄和端口。一旦輸入流關閉,再從它讀取數據時會觸發IOException。但是,有些類型的流可能仍答應對對象進行一定的操作。例如,用戶通常不希望從java.security.DigestInputStream中獲取報文摘要,除非已經讀取了所有數據并且關閉了輸入流。

 

看到這里或許你還會問怎么還有三個方法沒有呢,對,還有三個不常用的方法

public void mark(int readAheadLimit)

public void reset() throws IOException

public boolean markSupported();

這些方法答應程序備份和重新讀取已經讀取過的數據。要實現這個功能,需要用mark()方法在輸入流中的當前位置作個標記,在以后的某點可以使用reset()方法重新將流定位到標記處,隨后的讀取將返回從標記初開始的數據。但是,從標記處到重新將流定位點不能任意長。重新定位到標記處之前答應讀取的字節數就是由mark()的變量readAheadLimit決定。多長就會觸發IOException,而且任何指定時刻,輸入流中只可以有一個標記,假如標記了第二個標記,就會覆蓋第一個標記了。其實標記和重新設置位置都是通過存儲從內部緩沖區中的標記位置讀出每一字節來實現。最麻煩的狀況是,并非所有輸入流都支持標記和重新設置位置的。所以在設置之前要用markSupported()方法檢測一下。

實際上不支持標記和重新設置位置的流多于支持它們的流。Elliotte Rusty Harold大師覺得這幾個方法設計的標準不高,將功能性與一個許多甚至可能是大部分子類都不可用的抽象超類結合是一個相當拙劣的想法。最好是將這三個方法放在不同的接口中。提供類似于markSupported()方法在運行時進行功能性檢測是較為傳統,非面向對象的解決方法。面向對象的方法將通過接口和類把該方法嵌入到面向對象系統中,從而在編譯時檢測所有的流。

Java.io中總是支持標記的輸入流:BufferedInputStream和ByteArrayInputStream。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品国内视频| 色噜噜狠狠狠综合曰曰曰| 久久精品国产亚洲一区二区| 欧美成人免费在线视频| 日韩电影大片中文字幕| 久久久久五月天| 日韩欧美在线播放| 91精品在线影院| 久久全国免费视频| 日韩av一区二区在线| 亚洲视频电影图片偷拍一区| 国产噜噜噜噜噜久久久久久久久| 欧美日韩在线第一页| 亚洲xxxx做受欧美| 午夜精品福利视频| 成人乱人伦精品视频在线观看| 国产mv久久久| 在线播放日韩av| 国产日韩欧美一二三区| 在线播放国产一区二区三区| 亚洲男人天堂手机在线| 久久精品国产免费观看| 亚洲另类激情图| 国产精品美女免费| 福利二区91精品bt7086| 亚洲国产美女久久久久| 欧美区二区三区| 日本精品视频在线观看| 97色在线视频观看| 欧美激情手机在线视频| 91高清免费视频| 日韩av在线高清| 亚洲欧洲中文天堂| 疯狂欧美牲乱大交777| 亚洲国产一区自拍| 欧美尤物巨大精品爽| 久久久在线视频| 91久久久久久久久久| 亚洲日本中文字幕| 欧美日韩激情网| 91情侣偷在线精品国产| 欧美xxxx做受欧美.88| 亚洲免费视频网站| 欧美大片va欧美在线播放| 国产日韩在线精品av| 国语自产精品视频在线看一大j8| 色综合五月天导航| 伊人久久久久久久久久久久久| 日韩在线欧美在线国产在线| 久久久精品久久久久| 欧美理论片在线观看| 日韩免费观看视频| 欧美激情免费观看| 国产精品ⅴa在线观看h| 久久久久免费精品国产| 国产97色在线| 日韩av综合中文字幕| 国产97在线亚洲| 中文字幕欧美国内| 日韩女优在线播放| 国产精品美乳在线观看| 国产精品视频区1| 久久久亚洲福利精品午夜| 欧美激情va永久在线播放| 日韩欧美精品中文字幕| 另类少妇人与禽zozz0性伦| 久久久欧美精品| 亚洲人成电影网站色www| 日韩小视频在线观看| 亚洲理论电影网| 欧美性少妇18aaaa视频| 午夜精品久久久久久久99热| 精品久久在线播放| 久久精视频免费在线久久完整在线看| 久久久久久久网站| 久久天天躁夜夜躁狠狠躁2022| 日韩国产欧美精品在线| 日韩在线国产精品| 亚州av一区二区| 久久久91精品国产一区不卡| 在线播放日韩精品| 日韩中文在线视频| 久久久亚洲国产天美传媒修理工| 欧美性生交xxxxx久久久| 在线观看日韩欧美| 国产精品国内视频| 亚洲欧美日韩天堂一区二区| 91免费综合在线| 日韩中文字幕在线视频播放| 亚洲在线免费观看| 欧美高清自拍一区| 亚洲天堂第一页| 亚洲精品国精品久久99热一| 最好看的2019年中文视频| 九九热精品在线| 亚洲a区在线视频| 久久久国产精品亚洲一区| 热久久这里只有精品| 欧美视频一二三| 日韩精品免费综合视频在线播放| 亚洲国产精品久久| 国产成人综合一区二区三区| 国产精品吴梦梦| 午夜精品视频在线| 亚洲一区二区三区xxx视频| 国产精品成av人在线视午夜片| 国产在线精品成人一区二区三区| www.欧美精品一二三区| 日韩在线观看高清| 人人爽久久涩噜噜噜网站| 欧美激情在线视频二区| 国产视频精品久久久| 亚洲国产精品成人一区二区| 日韩成人激情视频| 最近2019中文字幕大全第二页| 亚洲国产高清高潮精品美女| 成人乱色短篇合集| 色婷婷成人综合| 波霸ol色综合久久| 一本一本久久a久久精品牛牛影视| 久久精品99久久久久久久久| 久久久成人精品| 欧美日韩国产第一页| 亚洲欧美另类人妖| 国产欧美日韩亚洲精品| 日日摸夜夜添一区| 欧美日韩中文在线| 色综合导航网站| 丝袜美腿亚洲一区二区| 国产成人精品av在线| 欧美成人一区二区三区电影| 日韩欧美在线视频日韩欧美在线视频| 亚洲欧美激情四射在线日| 国产日韩精品入口| 日韩亚洲一区二区| 亚洲国产天堂久久综合| 国产午夜精品美女视频明星a级| 亚洲韩国青草视频| 国产精品一二区| 96精品久久久久中文字幕| 国产日韩在线视频| 亚洲综合日韩中文字幕v在线| 91情侣偷在线精品国产| 欧美日韩国产在线看| 精品国产一区av| xvideos亚洲人网站| 91精品久久久久久久久久久久久| 久久精品国产69国产精品亚洲| 91精品国产高清久久久久久| 亚洲福利精品在线| 亚洲va久久久噜噜噜| 97婷婷涩涩精品一区| 欧美一级黑人aaaaaaa做受| 亚洲va码欧洲m码| 成人黄色免费网站在线观看| 97国产精品免费视频| 精品视频偷偷看在线观看| 国内精品模特av私拍在线观看| 亚洲无限av看| 狠狠干狠狠久久| 久久免费精品视频| 清纯唯美亚洲综合| 亚洲电影中文字幕| 欧美色图在线视频|