歷史系統將文檔(Word、PDF、圖片等)以 TEXT 或 IMAGE 類型存儲在 SQL Server 中,需遷移至文件系統。字段內容為 Base64 編碼字符串。
import java.io.*;
import java.sql.*;
import org.dbunit.util.Base64; // 或 Apache Commons Codec
public class BlobExporter {
public static void main(String[] args) throws Exception {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url = "jdbc:sqlserver://localhost:1433;DatabaseName=test1";
try (Connection conn = DriverManager.getConnection(url, "sa", "123456");
PreparedStatement ps = conn.prepareStatement("SELECT FileName, Content FROM aa");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
String fileName = rs.getString("FileName");
String base64 = rs.getString("Content");
byte[] data = Base64.decode(base64);
writeFile(data, "D:/doc", fileName);
}
}
}
private static void writeFile(byte[] data, String dirPath, String fileName) {
File dir = new File(dirPath);
if (!dir.exists()) dir.mkdirs();
File file = new File(dir, fileName);
try (FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
bos.write(data);
System.out.println("導出:" + file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
ResultSet.getString 適合中小文本;大對象建議 getBinaryStream() 分塊讀取,避免 OOM;java.util.Base64 (Java 8+) 或 Apache Commons Codec,org.dbunit.util.Base64 較舊;try-with-resources 自動關閉連接、流,防洩漏;mkdirs() 遞歸創建父目錄;BufferedOutputStream 提升寫入吞吐。try (InputStream is = rs.getBinaryStream("Content");
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
byte[] buf = new byte[8192];
int len;
while ((len = is.read(buf)) != -1) {
bos.write(buf, 0, len);
}
}
避免將完整 Base64 字符串載入 JVM 堆,支援 GB 級大對象導出。
SELECT 權限,文件目錄需寫入權限;mssql-jdbc 12.x+ 支援 JDK 11+,舊版 sqljdbc4 僅支援 JDK 8。