从 uCanAccess 结果集中获取乱码
Obtainig illegible characters from uCanAccess result set
我正在查询一个包含西班牙字符的旧 Access 97 数据库 ñ á é í ó ú
。我可以使用 access 很好地读取字符,所以我假设它使用 ISO-8859-1
但是我无法将它们转换为 UTF-8.
不确定我的问题是否与我的连接有关:
public static Connection baseAccess(String base) {
try {
java.util.Properties propiedades = new java.util.Properties();
propiedades.put("charSet", "ISO-8859-1");
return DriverManager.getConnection(String.format("jdbc:ucanaccess://%s", base),propiedades);
} catch (SQLException ex) {}
}
或者我对字符串的解析:
try (ResultSet rs = UtileriaDb.baseAccess(contabilidad).createStatement().executeQuery(sql);){
while(rs.next()){
String fromAccess = rs.getString(1);
System.out.println(fromAccess);
String transformed = new String(fromAccess.getBytes("ISO-8859-1"),"UTF-8");
System.out.println(transformed);
}
} catch (Exception ex) { }
所以当我期望时:
Año Café
我得到:
A�o Caf�
A?o Caf?
通过执行以下操作从结果集中获取字节内容进行了尝试:byte[] fromAccess = rs.getBytes(1);
但出现异常
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.4 incompatible data type in conversion: from SQL type VARCHAR to [B, value: myText
at net.ucanaccess.jdbc.UcanaccessResultSet.getBytes(UcanaccessResultSet.java:339)
所以这是一条死胡同。有没有其他方法可以解决这个问题?
正如@Scratte 正确指出的那样,rs.getString(1)
正在返回一个已经包含替换字符的字符串。感谢他帮助我指向 and this discussion
我最终实现了 ucanaccess JackcessOpenerInterface
并且工作得很好
package com.company.somepackage;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import net.ucanaccess.jdbc.JackcessOpenerInterface;
public class CharsetOpener implements JackcessOpenerInterface {
public Database open(File f, String pwd) throws IOException {
DatabaseBuilder db = new DatabaseBuilder(f);
db.setCharset(Charset.forName("ISO-8859-1"));
try {
db.setReadOnly(false);
return db.open();
} catch (IOException e) {
db.setReadOnly(true);
return db.open();
}
}
}
并在我的连接生成器中实现:
public static Connection baseAccess(String base) {
try {
java.util.Properties propiedades = new java.util.Properties();
propiedades.put("jackcessOpener", "com.company.somepackage.CharsetOpener");
return DriverManager.getConnection(String.format("jdbc:ucanaccess://%s", base),propiedades);
} catch (SQLException ex) {}
}
请注意实际的 属性 是 jackcessOpener
并且必须指向完全限定的 class 名称。
我正在查询一个包含西班牙字符的旧 Access 97 数据库 ñ á é í ó ú
。我可以使用 access 很好地读取字符,所以我假设它使用 ISO-8859-1
但是我无法将它们转换为 UTF-8.
不确定我的问题是否与我的连接有关:
public static Connection baseAccess(String base) {
try {
java.util.Properties propiedades = new java.util.Properties();
propiedades.put("charSet", "ISO-8859-1");
return DriverManager.getConnection(String.format("jdbc:ucanaccess://%s", base),propiedades);
} catch (SQLException ex) {}
}
或者我对字符串的解析:
try (ResultSet rs = UtileriaDb.baseAccess(contabilidad).createStatement().executeQuery(sql);){
while(rs.next()){
String fromAccess = rs.getString(1);
System.out.println(fromAccess);
String transformed = new String(fromAccess.getBytes("ISO-8859-1"),"UTF-8");
System.out.println(transformed);
}
} catch (Exception ex) { }
所以当我期望时:
Año Café
我得到:
A�o Caf�
A?o Caf?
通过执行以下操作从结果集中获取字节内容进行了尝试:byte[] fromAccess = rs.getBytes(1);
但出现异常
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.4 incompatible data type in conversion: from SQL type VARCHAR to [B, value: myText
at net.ucanaccess.jdbc.UcanaccessResultSet.getBytes(UcanaccessResultSet.java:339)
所以这是一条死胡同。有没有其他方法可以解决这个问题?
正如@Scratte 正确指出的那样,rs.getString(1)
正在返回一个已经包含替换字符的字符串。感谢他帮助我指向
我最终实现了 ucanaccess JackcessOpenerInterface
并且工作得很好
package com.company.somepackage;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import net.ucanaccess.jdbc.JackcessOpenerInterface;
public class CharsetOpener implements JackcessOpenerInterface {
public Database open(File f, String pwd) throws IOException {
DatabaseBuilder db = new DatabaseBuilder(f);
db.setCharset(Charset.forName("ISO-8859-1"));
try {
db.setReadOnly(false);
return db.open();
} catch (IOException e) {
db.setReadOnly(true);
return db.open();
}
}
}
并在我的连接生成器中实现:
public static Connection baseAccess(String base) {
try {
java.util.Properties propiedades = new java.util.Properties();
propiedades.put("jackcessOpener", "com.company.somepackage.CharsetOpener");
return DriverManager.getConnection(String.format("jdbc:ucanaccess://%s", base),propiedades);
} catch (SQLException ex) {}
}
请注意实际的 属性 是 jackcessOpener
并且必须指向完全限定的 class 名称。