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(); }
寫在最後
哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!