需求描述:
????????在對接電子病歷系統與河北CA,進行免密文件簽章的時候,兩者系統入參不同,前者是pdf文件,base64格式;后者要求File類型的PDF文件。
????????在業務中間層開發時,則需要接收EMR側提供的base64格式字符串,并將其轉化為臨時PDF文件(支持指定位置,若無則默認存于當前用戶下的臨時文件目錄),以供CA側進行文件簽。
注意事項:
資源管理:ByteArrayInputStream
?和?FileOutputStream
?都是需要顯式關閉的資源。可以使用?try-with-resources
?來自動管理這些資源,避免資源泄漏。- Base64 編碼與解碼優化(優化點,考慮病歷文件最多10M左右,則無需考慮此問題):Base64.getEncoder().encodeToString() 和 Base64.getDecoder().decode() 可以處理較大的文件,但對于大文件,使用流的方式進行分塊處理會更加高效,避免內存溢出。
代碼實現邏輯:
-
將 PDF 文件轉換為 Base64 編碼字符串:
convertPdfToBase64()
方法讀取文件內容并將其轉換為 Base64 字符串。
-
將 Base64 字符串轉換回 PDF 文件:
convertBase64ToPdfInMemory()
方法將 Base64 字符串解碼,并返回?ByteArrayInputStream
,其中包含轉換后的 PDF 數據。
-
將內存中的 PDF 寫入臨時文件:
createTempFileFromStream()
方法接受一個?ByteArrayInputStream
,并將其中的字節數據寫入到臨時文件。
-
刪除臨時文件:
- 文件處理完畢后,程序刪除臨時文件。
package com.bsoft.server.utils;import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;public class PdfToBase64Converter {public static void main(String[] args) {String pdfFilePath = "C:\\Users\\19079\\Desktop\\123.pdf"; // 替換為你的輸入PDF文件路徑String tempDirPath = "C:\\Users\\19079\\Desktop"; // 替換為你想要的臨時目錄路徑,留空則使用默認臨時目錄try {// 將 PDF 轉換為 Base64String base64String = convertPdfToBase64(pdfFilePath);System.out.println("Base64 Encoded PDF:");System.out.println(base64String);// 將 Base64 轉換回內存中的 PDFByteArrayInputStream pdfInMemory = convertBase64ToPdfInMemory(base64String);// 將內存中的 PDF 寫入臨時文件File tempFile = createTempFileFromStream(pdfInMemory, tempDirPath);System.out.println("臨時 PDF 文件創建位置: " + tempFile.getAbsolutePath());// 現在,您可以使用 tempFile 進行進一步處理System.out.println("PDF 文件大小: " + tempFile.length() + " bytes");// TODO 根據需要處理文件...// 處理后刪除臨時文件if (tempFile.delete()) {System.out.println("已成功刪除臨時文件。");} else {System.out.println("無法刪除臨時文件。");}} catch (IOException e) {System.err.println("IOException occurred: " + e.getMessage());e.printStackTrace();}}public static String convertPdfToBase64(String filePath) throws IOException {byte[] fileContent = Files.readAllBytes(Paths.get(filePath));return Base64.getEncoder().encodeToString(fileContent);}public static ByteArrayInputStream convertBase64ToPdfInMemory(String base64String) throws IOException {byte[] decodedBytes = Base64.getDecoder().decode(base64String);return new ByteArrayInputStream(decodedBytes);}public static File createTempFileFromStream(ByteArrayInputStream inputStream, String dirPath) throws IOException {File tempDir = (dirPath != null && !dirPath.isEmpty()) ? new File(dirPath) : new File(System.getProperty("java.io.tmpdir"));if (!tempDir.exists()) {throw new IOException("指定目錄不存在: " + dirPath);}// 創建臨時文件File tempFile = Files.createTempFile(tempDir.toPath(), "temp", ".pdf").toFile();// 確保 JVM 退出時刪除該文件tempFile.deleteOnExit();// 使用 try-with-resources 自動關閉資源try (FileOutputStream fos = new FileOutputStream(tempFile)) {byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {fos.write(buffer, 0, bytesRead);}}return tempFile;}
}