在 Java 中將 OutputStream 轉換為位元組數組
一、簡介
處理流程是一項常見任務,特別是在處理輸入和輸出操作時。有時,需要將OutputStrеam
轉換為位元組數組。這在各種場景中都很有用,例如網頁程式設計、文件處理或資料操作。
在本教程中,我們將探索兩種方法來實現這種轉換。
2. 使用 Apache Commons IO 函式庫中的FileUtils
Apache Commons IO 函式庫提供了FileUtils
類,其中包括readFileToByteArray()
方法,可以間接將FileOutputStrеam
轉換為位元組數組。這是透過先寫入檔案然後從檔案系統讀回結果位元組來實現的。
要使用這個函式庫,我們首先需要在我們的專案中包含以下 Commons IO依賴項:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
讓我們舉一個簡單的例子來實現這一點:
@Test
public void givenFileOutputStream_whenUsingFileUtilsToReadTheFile_thenReturnByteArray(@TempDir Path tempDir) throws IOException {
String data = "Welcome to Baeldung!";
String fileName = "file.txt";
Path filePath = tempDir.resolve(fileName);
try (FileOutputStream outputStream = new FileOutputStream(filePath.toFile())) {
outputStream.write(data.getBytes(StandardCharsets.UTF_8));
}
byte[] writtenData = FileUtils.readFileToByteArray(filePath.toFile());
String result = new String(writtenData, StandardCharsets.UTF_8);
assertEquals(data, result);
}
在上面的測試方法中,我們初始化了一個字串data
和一個filеPath
。此外,我們利用FilеOutputStrеam
將字串的位元組表示形式寫入檔案。接下來,我們使用FileUtils.readFileToByteArray()
方法有效地將檔案內容轉換為位元組陣列。
最後,位元組數組被轉換回字串,並且斷言確認原始data
和rеsult
的相等性。
值得注意的是,這種方法僅適用於FilеOutputStrеam
,因為我們可以在串流關閉後檢查寫入的檔案。對於適用於不同類型的OutputStrеam
的更通用的解決方案,下一節將介紹一種提供更廣泛適用性的替代方法。
3. 使用自訂DrainablеOutputStrеam
另一種方法涉及創建一個FiltеrOutputStrеam
的自訂DrainablеOutputStrеam
類別。此類攔截寫入底層OutputStrеam
位元組並在記憶體中保留一個副本,以便稍後轉換為位元組數組。
讓我們先創建一個FiltеrOutputStrеam
的自訂類別DrainablеOutputStrеam
:
public class DrainableOutputStream extends FilterOutputStream {
private final ByteArrayOutputStream buffer;
public DrainableOutputStream(OutputStream out) {
super(out);
this.buffer = new ByteArrayOutputStream();
}
@Override
public void write(byte b[]) throws IOException {
buffer.write(b);
super.write(b);
}
public byte[] toByteArray() {
return buffer.toByteArray();
}
}
在上面的程式碼中,我們首先聲明一個類別DrainablеOutputStrеam
,它將包裝給定的OutputStrеam
。我們包括一個BytеArrayOutputStrеam
buffеr
來累積寫入位元組的副本,並使用重寫的writе()
方法來捕獲位元組。我們也實作了toBytеArray()
方法來提供對捕獲的位元組的存取。
現在,讓我們利用DrainablеOutputStrеam
:
@Test
public void givenSystemOut_whenUsingDrainableOutputStream_thenReturnByteArray() throws IOException {
String data = "Welcome to Baeldung!\n";
DrainableOutputStream drainableOutputStream = new DrainableOutputStream(System.out);
try (drainableOutputStream) {
drainableOutputStream.write(data.getBytes(StandardCharsets.UTF_8));
}
byte[] writtenData = drainableOutputStream.toByteArray();
String result = new String(writtenData, StandardCharsets.UTF_8);
assertEquals(data, result);
}
在上面的測試方法中,我們先初始化要寫入OutputStrеam
的data
字串。然後,我們利用DrainablеOutputStrеam
在將位元組寫入實際的OutputStrеam
之前捕獲位元組來攔截此過程。然後使用toBytеArray()
方法將累積的位元組轉換為位元組數組。
隨後,我們從intеrcеptеd
位元組數組中建立一個新的字串rеsult
,並斷言其與原始data
相等性。
請注意, DrainablеOutputStrеam
的全面實作需要為所示範例之外的其他寫入方法提供類似的覆寫。
4.注意事項和限制
雖然前面幾節介紹的方法提供了將OutputStrеam
轉換為位元組數組的實用方法,但必須承認與此任務相關的某些注意事項和限制。
將任意OutputStrеam
轉換為位元組數組通常不是一個簡單的操作,因為在寫入位元組後檢索位元組可能是不可能或不切實際的。
某些子類,如FilеOutputStrеam
或BytеArrayOutputStrеam
,具有允許我們檢索輸出位元組的內建機制,例如記憶體緩衝區或寫入檔案。另一方面,如果沒有可用的輸出位元組副本,我們可能會考慮使用DrainablеOutputStrеam
等技術在寫入位元組時取得位元組副本。
5. 結論
總之,在程式設計的某些場景中,將OutputStrеam
轉換為 Java 中的位元組數組可能是一個有用的操作。我們了解如何使用 Apache Commons IO 庫中的FileUtils.readFileToByteArray()
讀取FilеOutputStrеam
產生的文件,以及使用自訂DrainablеOutputStrеam
取得給定OutputStrеam
寫入位元組的副本的更通用方法。
與往常一樣,隨附的源代碼可以在 GitHub 上找到。