1. 程式人生 > 其它 >java 檔案File與byte[]陣列相互轉換的兩種方式

java 檔案File與byte[]陣列相互轉換的兩種方式

1.檔案轉byte[]

方式一:檔案輸入流

File file = new File("C:\\Users\\Marydon\\Desktop\\個人信用報告.pdf");
try {
    FileInputStream fis = new FileInputStream(file);
    // 強轉成int型別大小的陣列
    byte[] fileBytes = new byte[(int) file.length()];
    // 將pdf內容放到陣列當中
    fis.read(fileBytes);
    // 關閉檔案流
    fis.close();
    System.out.println(Arrays.toString(fileBytes));
} catch (IOException e) {
    e.printStackTrace();
}

  在這裡會觸發一個思考題:

  將檔案的長度型別long強制轉換成int,真的可以嗎?

  起初,我覺得這樣不妥,原因在於:假設當檔案的長度>Integer型別的最大值時,那就這樣肯定就不行了,byte[]將不是一個完整的檔案陣列集合,怎麼辦?

  我首先想到的是:

  我們在進行檔案流的讀寫操作時,通常使用的是這種方式

  寫到這裡,我才明白,這種迴圈讀取的方式是因為有地方可以接受讀取到的位元組,我們這裡呢?本來就是要用陣列接收的,現在接收不下,沒有辦法,要想實現的話,也就只能將檔案拆分成多個數字集合,這樣一來,和我的初衷背道而馳,我就是想要將它們融合到一個數組,顯然,這種方式是行不通的。

  接下來,我就查了在Java中,陣列的最大限制相關資訊:

  陣列的最大限制,理論值是:

  相當於2G的大小,對應應用記憶體的話是4G(源自網路,不知其真假性,如果有好心人進行測試一下,歡迎留言)

  當我建立一個最大的陣列時,結果如下:

  陣列所需記憶體超過了Java虛擬機器的記憶體,GAME OVER。

  然後,繼續查:
  瞭解到:Java陣列最大容量同時受兩方面限制

  一是:陣列可索引的最大元素(也就是Integer的最大值);二是:應用程式可用的記憶體量(也就是JVM的容量)。
  走到這裡,基本上恍然大悟啦:

  只要我們能將檔案成功轉換成單個數組,就說明:

  檔案的長度必然<陣列容量的最大值,否則執行起來肯定報錯。

  所以,上述程式碼中將檔案的長度型別long強制轉換成int,是完全可以的,如果不可以(也就是檔案超過了陣列最大容量),那就不用考慮將檔案轉單個數組的實現方式啦。

  另外,如果你想用BufferInputStream來加快讀取速度的話,也是可以噠。

  對於有強迫症的人來說,強轉還是很讓人不舒服的,可以使用下面程式碼,一勞永逸

  推薦使用

File file = new File("C:\\Users\\Marydon\\Desktop\\個人信用報告.pdf");
try {
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    // 以位元組流的大小來指定陣列大小
    byte[] fileBytes = new byte[bis.available()];
    // 將pdf內容放到陣列當中
    bis.read(fileBytes);
    // 關閉檔案流
    bis.close();
    System.out.println(Arrays.toString(fileBytes));
} catch (IOException e) {
    e.printStackTrace();
} 

方式二:原生工具類Files(不推薦)

  使用條件:>=JDK1.8

try {
    // 方式一
    byte[] bytes = Files.readAllBytes(Paths.get("C:\\Users\\Marydon\\Desktop\\個人信用報告.pdf"));
    // 方式二
    // bytes = Files.readAllBytes(new File(("C:\\Users\\Marydon\\Desktop\\個人信用報告.pdf")).toPath());
    System.out.println(Arrays.toString(bytes));
} catch (IOException e) {
    e.printStackTrace();
}

  但是,這種方式比較雞肋,大檔案(100多兆)讀取容易記憶體溢位。

  如果發現讀取完畢,獲得的陣列始終為空[],很有可能是你的原檔案已經被破壞

2.byte[]轉檔案

方式一:檔案輸出流

// 檔案流
byte[] fileBytes = {37, 80, 68, 70, 45, 49, 46, 52, 10, 37, -30, -29, -49, -45, 10, 50, 32, 48, 32, 111, 98, 106, 10, 60, 60, 47, 84, 121, 112, 101, 47, 88, 79};
try {
    // 將要輸出的檔案
    File outFile = new File("C:\\Users\\Marydon\\Desktop\\aa.pdf");
    // 檔案轉輸出流
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outFile));
    // 將檔案流寫入檔案
    bos.write(fileBytes);
    bos.close();
} catch (IOException e) {
    e.printStackTrace();
}

  上面提供的檔案位元組陣列,是無法轉成正常檔案的哦,我這裡僅提供實現方法

方式二:原生工具類Files

// 檔案流
byte[] fileBytes = {37, 80, 68, 70, 45, 49, 46, 52, 10, 37, -30, -29, -49, -45, 10, 50, 32, 48, 32, 111, 98, 106, 10, 60, 60, 47, 84, 121, 112, 101, 47, 88, 79};
try {
    // 將陣列輸出到指定檔案當中
    Files.write(Paths.get("C:\\Users\\Marydon\\Desktop\\aa.pdf"), fileBytes);
} catch (IOException e) {
    e.printStackTrace();
}

  

寫在最後

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

相關推薦: