gpt4 book ai didi

java - 在使用 MS Access 创建的 Oracle10g 数据库中 Access BLOBS

转载 作者:行者123 更新时间:2023-11-30 09:14:51 25 4
gpt4 key购买 nike

我正在编写一个 Java(好的,Groovy,但这并不重要)迁移脚本来将 BLOB 字段从 Oracle10g 数据库复制到另一个数据库。数据由 MS Access 应用程序创建。这些文件的编码似乎不正确,我猜测 MS Access 或 ODBC 驱动程序以某种方式操纵了该文件。

使用查询 SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET'; 我发现源数据库具有字符集 WE8MSWIN1252

源表定义为:

CREATE TABLE CTR_DOCUMENTS (
CTR_ID NUMBER(11) NOT NULL,
CTR_A_ID NUMBER(11),
CTR_FILENAME VARCHAR2(260 Char) NOT NULL,
CTR_COMMENT VARCHAR2(255 Char),
CTR_DATE DATE,
CTR_DATA BLOB
)

我像这样 Access blob:

def blob = sourceDB.firstRow("SELECT CTR_DATA FROM CTR_DOCUMENTS WHERE CTR_ID = ?",
[id]).CTR_DATA
def blobSize = blob.length()
def blobStream = blob.getBinaryStream()
byte[] byteArray = new byte[blobSize]
blobStream.read(byteArray)

我将一些 blob 保存为文件,编码看起来很奇怪,文件无法被他们的程序打开。第二个字节始终为 00:

0000000: 2500 5000 4400 4600 2d00 3100 2e00 3500  %.P.D.F.-.1...5.

我还观察到使用 SQL 客户端(SQL Workbench/J、SQLDeveloper、TOAD) Access BLOBS 时的相同行为。

对我来说,看起来我必须将文件从 Windows-1252 转换为 UTF8,但这不起作用。我在这里遗漏了什么吗?

最佳答案

如果没有其他原因,出于诊断目的,我将从哪里开始扫描输入 BLOB 样本中的字节数组,以查看是否每个第二个字节实际上都是 0x00,并每隔一个写入(非零)字节到 bytesOut 字节数组。如果成功,我会将 bytesOut 数组写入文件并查看它们现在是否是有效的 PDF 文档。例如:

public static void main(String[] args) {
try {
String connectionUrl = "";
connectionUrl =
"jdbc:sqlserver://localhost;" +
"instanceName=SQLEXPRESS;" +
"databaseName=myDb;" +
"integratedSecurity=true";
Connection con = DriverManager.getConnection(connectionUrl);

String SQL =
"SELECT CTR_ID, CTR_FILENAME, CTR_DATA " +
"FROM CTR_DOCUMENTS " +
"WHERE CTR_ID BETWEEN 1 AND 5";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(SQL);

while (rs.next()) {
boolean writeFile = true;
byte[] bytesIn = rs.getBytes("CTR_DATA");
//scan input byte array and copy every second byte to output byte array
byte[] bytesOut = new byte[bytesIn.length / 2];
for (int i = 0; i < bytesIn.length; i++) {
if ((i % 2) == 1) {
if (bytesIn[i] != 0x00) {
System.out.println(String.format("Darn. bytesIn value at offset %d is not 0x00. Skipping...", i));
writeFile = false;
break;
}
}
else {
bytesOut[i / 2] = bytesIn[i];
}
}
if (writeFile) {
String outFile =
"C:\\__tmp\\pdfTest\\" + rs.getString("CTR_FILENAME");
FileOutputStream fos = new FileOutputStream(outFile);
fos.write(bytesOut);
fos.close();
System.out.println(String.format("\"%s\" created.", outFile));
}
}
rs.close();
con.close();
} catch(Exception e) {
System.out.println(e.getMessage());
System.exit(0);
}
}

推理是,如果在某个过程中,某个进程采用了它认为是单字节字符的“字符串”(例如,Windows-1252)并通过简单地转换为 Unicode(例如,UCS-2LE)在每个字符后插入 0x00(不以其他方式破坏实际数据字节),那么最直接的解决方案就是再次取出那些 0x00 字节。

关于java - 在使用 MS Access 创建的 Oracle10g 数据库中 Access BLOBS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20248894/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com