需求描述:
在对接电子病历系统与河北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 转换为 Base64
String base64String = convertPdfToBase64(pdfFilePath);
System.out.println("Base64 Encoded PDF:");
System.out.println(base64String);
// 将 Base64 转换回内存中的 PDF
ByteArrayInputStream 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;
}
}