“你好,阿米戈!今天我們要再次深入研究InputStreamOutputStream是如何工作的。最初的解釋實際上有點簡單。它們不是接口。它們是抽像類,它們甚至有幾個實現方法。讓我們看看他們有什麼方法:”

輸入流方法 該方法的作用
int read(byte[] buff);
此方法立即將一個字節塊讀入緩衝區字節數組),直到緩衝區已滿或源沒有更多字節可讀。
該方法返回實際讀取的字節數(可以小於數組長度)
int read();
此方法讀取一個字節並將其返回。結果被擴大到一個 int 的外觀。如果沒有更多字節要讀取,則該方法返回 -1。
int available();
此方法返回未讀(可用)字節數。
void close();
此方法“關閉”流。當你完成流的工作時,你會調用它。
然後該對象執行關閉文件等所需的內務處理操作。
此時,您不能再從流中讀取任何數據。

“所以我們不僅可以讀取單個字節,還可以讀取整個塊?”

“確切地。”

“我們也可以寫整塊嗎?”

“是的,檢查一下:”

輸出流方法 該方法的作用
void write(int c);
此方法寫入一個字節。int 類型縮小到一個字節。多餘的部分被簡單地丟棄。
void write(byte[] buff);
此方法寫入一個字節塊。
void write(byte[] buff, int from, int count);
此方法寫入字節塊的一部分。它用於字節數組可能未完全填充的情況。
void flush();
如果流在內部存儲任何尚未寫入的數據,則此方法會強制將其寫入。
void close();
此方法“關閉”流。當你完成流的工作時,你會調用它。
然後該對象執行關閉文件等所需的內務處理操作。您不能再向流中寫入數據,系統會自動調用 flush。

“如果我們一次讀取整個塊而不是單個字節,文件複製代碼會是什麼樣子?”

“嗯。像這樣:”

複製磁盤上的文件
public static void main(String[] args) throws Exception
{
 //Create a stream to read bytes from a file
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 //Create a stream to write bytes to a file
 FileOutputStream outputStream = new FileOutputStream("c:/result.txt");

  byte[] buffer = new byte[1000];
 while (inputStream.available() > 0) //as long as there are unread bytes
 {
  //Read the next block of bytes into buffer, and store the actual number of bytes read in count.
  int count = inputStream.read(buffer);
  outputStream.write(buffer, 0, count); //Write a block (part of a block) to the second stream
 }

 inputStream.close(); //Close both streams. We don't need them any more.
 outputStream.close();
}

“我了解有關緩衝區的一切,但這個計數變量是什麼?”

“當我們從一個文件中讀取最新的數據塊時,我們可能會得到 328 個字節而不是 1000 個字節。因此當我們寫入數據時,我們需要表明我們沒有寫入整個塊——只寫入前 328 個字節字節。”

當我們讀取最後一個塊時,read方法將返回實際讀取的字節數。每次我們讀取一個塊時都是 1000,除了最後一個塊,當我們得到 328 時。

所以當我們寫一個塊時,我們表明不是緩衝區中的所有字節都應該被寫入,只是 328(即存儲在 count 變量中的值)。

“現在一切都清楚了。謝謝,艾莉。”