欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 輸入流中的read(byte[] b)方法詳解

 更新時間:2021年01月20日 16:02:44   作者:Rrrrrandom  
這篇文章主要介紹了Java 輸入流中的read(byte[] b)方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

我就廢話不多說了,大家還是直接看代碼吧~

public int read(byte[] b)
  throws IOException

從一個輸入流中讀取一定數(shù)量的字節(jié),并將這些字節(jié)存儲到其緩沖作用的數(shù)組b中。這個函數(shù)會返回一次性讀取的字節(jié)數(shù)。

這個函數(shù)是一個阻塞式的函數(shù),當(dāng)它讀到有效數(shù)據(jù)、確認的文件尾(EOF)或者拋出一個異常時它才會執(zhí)行其他語句,否則一直停在read()函數(shù)處等待。

比如下面的列子:

ServerSocket server = new ServerSocket(port)
Socket client = server.accept();
BufferedInputStream bis = new BufferedInputStream(client.getInputStream);
byte[] box = new byte[1024];
int len = 0;
while(-1!=(len = bis.read(box))) {
 System.out.println(len);
 String msg = new String(box, 0, len);
}語句1;語句二;

在這種情況下,當(dāng)從客戶端接收了一條信息并轉(zhuǎn)成msg字符串后,while循環(huán)會又回到read()函數(shù),不會跳出循環(huán)執(zhí)行語句一和二。

因為這時read()函數(shù)并沒有遇到文件尾或者拋出異常,所以下一次while條件判斷read()函數(shù)會一直等待有效數(shù)據(jù)的輸入,而不是返回-1。此時整個程序?qū)枞谶@里。

如果我們是從文件用這個函數(shù)以這種while循環(huán)方式讀取數(shù)據(jù)的話并不會遇到這個問題,因為讀到最后會遇到EOF的。

如果用這種方式讀取控制臺的輸入的話,我們可以選擇不要while循環(huán)?;蛘咴O(shè)置條件跳出循環(huán),即如果len小于box的長度話就跳出循環(huán)。

我們還可以選擇用DataInputStream的readUTF()函數(shù)也可以。還有就是我們可以采用監(jiān)聽機制,當(dāng)監(jiān)聽到輸入流中有數(shù)據(jù)之后再讀取。

補充:教你完全理解IO流里的 read(),read(byte[]),read(byte[],int off,int len)以及write

好的我們先來講它們的作用,然后再用代碼來實現(xiàn)給大家看

read():

1.從讀取流讀取的是一個一個字節(jié)

2.返回的是字節(jié)的(0-255)內(nèi)的字節(jié)值

3.讀一個下次就自動到下一個,如果碰到-1說明沒有值了.

read(byte[] bytes)

1.從讀取流讀取一定數(shù)量的字節(jié),如果比如文件總共是102個字節(jié)

2.我們定義的數(shù)組長度是10,那么默認前面10次都是讀取10個長度

3.最后一次不夠十個,那么讀取的是2個

4.這十一次,每次都是放入10個長度的數(shù)組.

read(byte[] bytes,int off ,int len)

1.從讀取流讀取一定數(shù)量的字節(jié),如果比如文件總共是102個字節(jié)

2.我們定義的數(shù)組長度是10,但是這里我們寫read(bytes,0,9)那么每次往里面添加的(將只會是9個長度),就要讀12次,最后一次放入3個.

3.所以一般讀取流都不用這個而是用上一個方法:read(byte[]);

下面講解write

write(int i);

直接往流寫入字節(jié)形式的(0-255)int值.

write(byte[] bytes);

往流里邊寫入緩沖字節(jié)數(shù)組中的所有內(nèi)容,不滿整個數(shù)組長度的”空余內(nèi)容”也會加入,這個下面重點講,

write(byte[] bytes,int off,int len);

1.這個是更嚴謹?shù)膶懛?在外部定義len,然后每次len(為的是最后一次的細節(jié)長度)都等于流往數(shù)組中存放的長度

2.如上述read(bytes),前面每次都放入十個,第十一次放入的是2個,如果用第二種write(bytes),將會寫入輸出流十一次,每次寫入十個長度,造成后面有8個空的,比原來的內(nèi)容多了

3.所以用write(byte[] bytes,int off,int len);就不會出現(xiàn)多出來的空的情況,因為最后一次len不同

下面是詳細的代碼

public class Test{
 public static void main(String[] args) throws Exception {
 UseTimeTool.getInstance().start();
 FileInputStream fis = new FileInputStream("D:\\1.mp3");
 FileOutputStream fos = new FileOutputStream("D:\\1copy.mp3");
 //(PS:一下3個大家分開來寫和測試,為了方便我都列出來了)
 /*--------------不使用緩沖--------------*/
 //如果不緩沖,花了差不多14"秒"
 int len = -1;
 while ((len = fis.read()) != -1) {
  //這里就不是長度的問題了,而是讀取的字節(jié)"內(nèi)容",讀到一個寫一個,相當(dāng)慢.
  System.out.println("len : "+ len); 
  fos.write(len);
 }
 /*--------------使用緩沖--------------*/
 //緩沖方法復(fù)制歌曲用了不到20"毫秒"
 //創(chuàng)建一個長度為1024的字節(jié)數(shù)組,每次都讀取5kb,目的是緩存,如果不用緩沖區(qū),用fis.read(),就會效率低,一個一個讀字節(jié),緩沖區(qū)是一次讀5000個
 byte[] bytes = new byte[1024*5];
 //每次都是從讀取流中讀取(5k)長度的數(shù)據(jù),然后再寫到文件去(5k的)數(shù)據(jù),注意,每次讀取read都會不同,是獲取到下一個,直到后面最后一個.
 while (fis.read(bytes)!=-1) {
  //write是最追加到文件后面,所以直接每次添5K.
  fos.write(bytes); 
 }
 /*--------------解釋len--------------*/
 //告訴你為什么用len
 byte[] bytes = new byte[1024*5];
 int len = -1;
 //解釋這個fis.read(bytes)的意思:從讀取流"讀取數(shù)組長度"的數(shù)據(jù)(打印len可知),并放入數(shù)組
 while ((len = fis.read(bytes,0,1024)) != -1) {
  //雖然數(shù)組長度的*5,但是這里我們設(shè)置了1024所以每次輸出1024
  System.out.println("len : "+ len);
  //因為每次得到的是新的數(shù)組,所以每次都是新數(shù)組的"0-len"
  fos.write(bytes,0,len);
 }
 fis.close();
 fos.close();
 UseTimeTool.getInstance().stop();
 }
}

為了方便大家,也給大家一個統(tǒng)計時間的工具類

class UseTimeTool {
 private static UseTimeTool utt = new UseTimeTool();
 private UseTimeTool() {
 }
 public static UseTimeTool getInstance() {
 return utt;
 }
 private long start;
 public void start() {
 start = System.currentTimeMillis();
 }
 public void stop() {
 long end = System.currentTimeMillis();
 System.out.println("所用時間 : " + (end - start) + "毫秒");
 }
}

好了最后一個:len問題 最后多出數(shù)組不滿的部分我特再寫一個出來給大家分析

首先,文本的內(nèi)容是

public class Test{
 public static void main(String[] args) throws Exception {
 UseTimeTool.getInstance().start();
 FileInputStream fis = new FileInputStream("D:\\a.txt");
 FileOutputStream fos = new FileOutputStream("D:\\acopy.txt");

不使用len:

byte[] bytes = new byte[1024*5];
 while (fis.read(bytes)!=-1) {
  fos.write(bytes); 
 }

得到的效果:

發(fā)現(xiàn)后續(xù)后很多的空部分,所以說不嚴謹

使用len:

byte[] bytes = new byte[1024*5];
 int len = -1;
 while ((len = fis.read(bytes,0,1024)) != -1) {
  fos.write(bytes,0,len);
 }

得到的效果

和原來一模一樣,講了那么多就是希望能幫助大家真正的理解。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • SpringBoot使用@ResponseBody返回圖片的實現(xiàn)

    SpringBoot使用@ResponseBody返回圖片的實現(xiàn)

    這篇文章主要介紹了SpringBoot使用@ResponseBody返回圖片的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • SpringBoot3整合SpringDoc實現(xiàn)在線接口文檔的詳細過程

    SpringBoot3整合SpringDoc實現(xiàn)在線接口文檔的詳細過程

    這篇文章主要介紹了SpringBoot3整合SpringDoc實現(xiàn)在線接口文檔的詳細過程,本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • 最新評論