在 Java 中將檔案轉換為位元組數組
1. 概述
在本快速教程中,我們將了解如何在 Java 中將檔案轉換為位元組數組。
首先,我們將學習如何使用內建的 JDK 解決方案來做到這一點。然後,我們將討論如何使用 Apache Commons IO 和 Guava 實現相同的結果。
2. 使用Java
JDK 提供了幾種將檔案轉換為位元組陣列的便捷方法。例如,我們可以使用java.io
或java.nio
套件來回答我們的中心問題。那麼,讓我們仔細看看每個選項。
2.1. FileInputStream
讓我們從使用 IO 套件中的FileInputStream
類別的最簡單的解決方案開始。通常,此類附帶以位元組形式讀取文件內容的方法。
例如,假設我們有一個名為sample.txt
的文件,其內容為“Hello World”
:
class FileToByteArrayUnitTest {
private static final String FILE_NAME = "src" + File.separator + "test" + File.separator + "resources" + File.separator + "sample.txt";
private final byte[] expectedByteArray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 };
@Test
void givenFile_whenUsingFileInputStreamClass_thenConvert() throws IOException {
File myFile = new File(FILE_NAME);
byte[] byteArray = new byte[(int) myFile.length()];
try (FileInputStream inputStream = new FileInputStream(myFile)) {
inputStream.read(byteArray);
}
assertArrayEquals(expectedByteArray, byteArray);
}
}
在這裡,我們使用給定的sample.txt
檔案創建了FileInputStream
類別的實例。此外,我們呼叫read(byte[] b)
方法將資料從FileInputStream
實例讀取到定義的位元組數組中。
值得注意的是,我們使用了try-with-resources
方法來有效處理資源的關閉。
2.2. Files#readAllBytes
或者,我們可以使用 NIO API 中的Files
類別。顧名思義,此實用程式類別提供了多個即用型靜態方法來處理檔案和目錄。
那麼,讓我們看看它的實際效果:
@Test
void givenFile_whenUsingNioApiFilesClass_thenConvert() throws IOException {
byte[] byteArray = Files.readAllBytes(Paths.get(FILE_NAME));
assertArrayEquals(expectedByteArray, byteArray);
}
正如我們所看到的, Files
類別附帶了readAllBytes()
方法,該方法會傳回指定路徑檔案中的所有位元組。有趣的是,當讀取位元組後,此方法會自動關閉檔案。
這裡另一個重要的警告是該方法不適用於讀取大檔案。因此,我們只能將它用於簡單的情況。
3. 使用 Apache Commons IO
另一個解決方案是使用 Apache Commons IO 函式庫。它提供了許多方便的實用程式類,我們可以使用它們來執行常見的 IO 任務。
首先,讓我們將commons-io
依賴項新增到pom.xml
檔案中:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.0</version>
</dependency>
3.1. FileUtils#readFileToByteArray
如名稱所示, FileUtils
類別提供了一組用於檔案操作的方法。在這些方法中,我們找到了readFileToByteArray()
方法:
@Test
void givenFile_whenUsingApacheCommonsFileUtilsClass_thenConvert() throws IOException {
byte[] byteArray = FileUtils.readFileToByteArray(new File(FILE_NAME));
assertArrayEquals(expectedByteArray, byteArray);
}
正如我們上面看到的, readFileToByteArray()
以簡單的方式將指定檔案的內容讀取到位元組數組中。此方法的好處是文件始終處於關閉狀態。
此外,此方法沒有Files#readAllBytes
的限制,且如果提供的檔案為 null,則會拋出NullPointerException
null.
3.2. IOUtils#toByteArray
Apache Commons IO 提供了另一個替代方案,我們可以使用它來實現相同的結果。它提供了IOUtils
類別來處理一般的 IO 流操作。
那麼,我們用一個實際的例子來說明IOUtils
的使用:
@Test
void givenFile_whenUsingApacheCommonsIOUtilsClass_thenConvert() throws IOException {
File myFile = new File(FILE_NAME);
byte[] byteArray = new byte[(int) myFile.length()];
try (FileInputStream inputStream = new FileInputStream(myFile)) {
byteArray = IOUtils.toByteArray(inputStream);
}
assertArrayEquals(expectedByteArray, byteArray);
}
簡而言之,該類別附帶了toByteArray()
方法,用於將InputStream
的資料作為byte[]
傳回。我們不需要在這裡使用BufferedInputStream
,因為此方法在內部緩衝內容。
4. 使用番石榴
Guava 庫是將檔案轉換為位元組數組時要考慮的另一個選擇。像往常一樣,在開始使用這個函式庫之前,我們需要將其依賴項新增至pom.xml
:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
4.1. Files#toByteArray
Guava 函式庫提供了自己版本的Files
類別。那麼,讓我們在實踐中來看看:
@Test
void givenFile_whenUsingGuavaFilesClass_thenConvert() throws IOException {
byte[] byteArray = com.google.common.io.Files.toByteArray(new File(FILE_NAME));
assertArrayEquals(expectedByteArray, byteArray);
}
簡而言之,我們使用toByteArray()
方法來取得包含給定檔案中所有位元組的位元組數組。
5. 結論
在這篇短文中,我們探索了使用 JDK 方法、Guava 和 Apache Commons IO 庫將檔案轉換為位元組數組的各種方法。
與往常一樣,本文中使用的程式碼可以在 GitHub 上找到。