编码字节数组

时间:2018-01-12 02:28:04

标签: java mysql arrays string utf-8

我正在为我的大学开发一个项目。我在尝试将字节数组转换为字符串时遇到了麻烦。

所以,首先我将MySql中的 long blob 类型列中的java文件的内容保存为:

Path path = Paths.get(file.getAbsolutePath());
Charset charset = StandardCharsets.UTF_8;
String fileContent = new String(Files.readAllBytes(path), charset);
...
String query = "INSERT INTO MY_TABLE(FILE_CONTENT) VALUES (?)";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setString(1, fileContent);
preparedStmt.executeUpdate();

该文件包含一些带有西班牙语重音的单词,这些单词正确插入数据库中(如图所示): data saved in MySql

稍后,在我的应用程序中,我需要阅读本专栏中的信息。我确实喜欢这个:

String query = "SELECT * FROM MY_TABLE";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next())
{
  Blob file= rs.getBlob("FILE_CONTENT");
  String fileContent= new String(file.getBytes(1l, (int) file.length()), StandardCharsets.UTF_8);

当我打印 fileContent 时,无法识别字符é。我得到一个类似这样的文字: driver.findElement(By.id("FNAME")).sendKeys("Leonardo Pa�z")

我已尝试过这些帖子中的建议 (encoding decoding of byte array to string without data loss), (Encode String to UTF-8), (Java Strings Character Encoding - For French - Dutch Locales) 以及一些像one这样的博客,但我找不到解决这个问题的方法。

任何帮助都将非常感激:)

1 个答案:

答案 0 :(得分:0)

你说FILE_CONTENT是一个blob,但是你使用setString()来设置它的数据。来自javadocs:

  

注意:setter方法(setShort,setString等)用于设置   IN参数值必须指定与其兼容的类型   定义了输入参数的SQL类型。例如,如果IN   参数有SQL类型INTEGER,那么应该使用方法setInt。

由于您的类型是blob,因此必须使用setBlob:

try (InputStream fileContent = Files.newInputStream(path))
{
    preparedStmt.setBlob(1, fileContent);
}

另一种方法是将SQL类型更改为其中一种TEXT类型,例如LONGTEXT(如果你期望大文件)。 BLOB对文本没有多大意义。然后你可以简单地使用setString()和getString():

rs.getString("FILE_CONTENT");

您还希望将数据库/表/列编码更改为UTF-8。

进一步解释:

使用setString()向数据库提供String时,Java和数据库都不知道有关原始文件编码的任何信息。数据库使用它的默认编码存储字符,可能是ISO_8859_1。由于ISO_8859_1具有字符é,因此您可以在MySQL工作台中看到它。然后,当您使用getBlob()获取数据并使用UTF-8对其进行解码时,é字符会丢失,因为文本不会存储为UTF-8。