`
wsql
  • 浏览: 11776736 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

数据库编程之编码转换实例:乱码分析

 
阅读更多

1问题描述

最近有人问我问题,说在Java中以UTF-8编码读UTF-8编码的文件test.htm,存入oracle数据库后再读出,一切正常。在Java中UTF-8编码读UTF-8编码的文件test.htm,存入kingbase数据库后再读出,文件中出现乱码,不知为何。

2具体现象

具体现象如下:

Java中读UTF-8编码的文件test.htm,存入数据库后再读出,文件中出现乱码

原文件图如下:



3 存入数据库再读出后出现乱码如下:



注:前面两幅图中“合资公司双方出资比例的问题”前面的那个“・”变成了“”。

4 相关代码

下面是模拟这个过程的读写文件和写读数据库的java代码:

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.sql.Clob;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class TestEoding {

public static void main(String[] args) throws Exception {

//create table and insert 1 recode

//oracle,kingbase

// create table t_test (id int,txt clob);

// insert into t_test (id,txt) values(1,'');

//pg

// create table t_test (id int,txt text);

// insert into t_test (id,txt) values(1,'');

//kingbase

String driver = "com.kingbase.Driver";

String url = "jdbc:kingbase://127.0.0.1:54321/BEIGANG?ClientEncoding=UNICODE";

String usr = "BEIGANG";

String passwd = "beigang";

String fn = "E:/test.htm";

/*

//pg

String driver = "org.postgresql.Driver";

String url = "jdbc:postgresql://127.0.0.1:5432/beigang";

String usr = "beigang";

String passwd = "beigang";

String fn = "E:/test.htm";

*/

if (args.length > 0) {

fn = args[0];

}

String value = getValue(fn);

testDB(driver, url, usr, passwd, fn + ".kb", value);

/*

//sqlserver

driver = "net.sourceforge.jtds.jdbc.Driver";

url = "jdbc:jtds:sqlserver://127.0.0.1:1433/beigang";

usr = "beigang";

passwd = "beigang";

testDB2(driver, url, usr, passwd, fn + ".mssql", value);

driver = "oracle.jdbc.driver.OracleDriver";

url = "jdbc:oracle:thin:@127.0.0.1:1521:beigang";

usr = "beigang";

passwd = "beigang";

testDB2(driver, url, usr, passwd, fn + ".oracle", value);

*/

}

protected static void testDB(String driver, String url, String usr,

String passwd, String fn, String value) throws SQLException,

Exception {

Class.forName(driver);

Connection conn = DriverManager.getConnection(url, usr, passwd);

String sql = "update t_test set txt = ? where id=1";

PreparedStatement stmt = conn.prepareStatement(sql);

stmt.setString(1, value);

stmt.executeUpdate();

stmt.close();

sql = "select txt from t_test where id=1";

stmt = conn.prepareStatement(sql);

ResultSet rs = stmt.executeQuery();

if (rs.next()) {

writeFile(fn, rs.getString(1));

}

/*

* pg

String sql = "update t_test set txt = '" +value +"' where id=1";

ResultSet rs;

stmt.executeUpdate(sql);

sql = "select txt from t_test where id=1";

rs = stmt.executeQuery(sql);

if (rs.next()) {

writeFile(fn, rs.getString(1));

}

*/

}

protected static void testDB2(String driver, String url, String usr,

String passwd, String fn, String value) throws SQLException,

Exception {

Class.forName(driver);

Connection conn = DriverManager.getConnection(url, usr, passwd);

String sql = "update t_test set txt = ? where id=1";

PreparedStatement stmt = conn.prepareStatement(sql);

stmt.setString(1, value);

stmt.executeUpdate();

stmt.close();

sql = "select txt from t_test where id=1";

stmt = conn.prepareStatement(sql);

ResultSet rs = stmt.executeQuery();

if (rs.next()) {

writeFile(fn, rs.getString(1));

}

}

private static void writeFile(String fn, String string) throws Exception {

FileOutputStream fos = new FileOutputStream(fn);

byte[] content = string.getBytes("UTF-8");

fos.write(content);

fos.flush();

fos.close();

}

private static String getValue(String fn) throws Exception {

ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);

FileInputStream fins = new FileInputStream(fn);

int b = -1;

while ((b = fins.read()) != -1) {

baos.write(b);

}

return baos.toString("UTF-8");

//return baos.toString("GBK");

}

}

4 结论

结果测试确认,发现oracle、kingbase等数据库中存在同样问题,问题原因是编码"UTF8"的字符0xe383bb(就是“・”)在"GBK"没有相对应物。刚开始说的oracle不出现乱码,而kingbase出现乱码是他搞错了数据库服务器端编码,oracle用来UTF-8的编码,kingbase用了GBK的编码导致。

根本原因是"UTF8"编码的字符0xe383bb(就是"")在"GBK"没有相对应物。

5 数据库字符集和编码转换

参见我的博客http://blog.csdn.net/beiigang/article/details/7051605

6

把test.htm传上来,压缩文件使test.rar,有兴趣可以实践下

看了一下,不知道怎么把附件传上来,不知道这儿有这个功能没


分享到:
评论

相关推荐

    数据库编程之编码转换实例--乱码分析

    NULL 博文链接:https://beigang.iteye.com/blog/1254750

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例031 Zend Studio编码格式的转换 56 实例032 Zend Studio中快捷键的运用 57 实例033 Zend Studio中部署Apache服务器 60 第2章 PHP基础 63 2.1 基本语法 64 实例034 在页面中打印PHP的配置信息 64 实例035 在页面...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例031 Zend Studio编码格式的转换 56 实例032 Zend Studio中快捷键的运用 57 实例033 Zend Studio中部署Apache服务器 60 第2章 PHP基础 63 2.1 基本语法 64 实例034 在页面中打印PHP的配置信息 64 实例035 在页面...

    PHP程序开发范例宝典III

    实例250 使用格式化函数转换查询条件的数据类型 385 实例251 在查询中使用字符串函数 387 实例252 在查询中使用日期函数 388 8.19 having语句应用 390 实例253 利用having语句过滤分组数据 390 ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例022 自动类型转换与强制类型转换 33 2.2 运算符 34 实例023 加密可以这样简单(位运算) 34 实例024 用三元运算符判断奇数和偶数 35 实例025 更精确地使用浮点数 35 实例026 不用乘法运算符实现2×16 37 实例027...

    C#编程经验技巧宝典

    C#编程经验技巧宝典源代码,目录如下: 第1章 开发环境 1 <br>1.1 Visual Studio开发环境安装与配置 2 <br>0001 安装Visual Studio 2005开发环境须知 2 <br>0002 配置合适的Visual Studio 2005...

    asp.net知识库

    C++ 泛型编程系列讲座之实施 泛型技巧系列:简单类型选择器 C# 泛型简介 我眼中的C#2.0新功能特性 泛型技巧系列:避免基类及接口约束 New Article 不该用Generics实现Abstract Factory的理由 C#2.0-泛型 C#2.0-...

    易语言程序免安装版下载

    取错误文本()”返回的文本是UTF-8编码(应是GB18030编码)。 -------------------------------------------------------------------------------- 易语言5.0 相对于易语言4.x更新说明(2010/02/01):  增加...

    ssh(structs,spring,hibernate)框架中的上传下载

    这样,我们就再没有必要通过硬编码的方式,先insert然后再update来完成Blob类型数据的持久化,这个原来难伺候的老爷终于被平民化了。关于lobHandler的配置请见本文后面的内容。  此外lazy="true"说明地返回整个...

    Java学习笔记-个人整理的

    {12.5}操作符与实例}{154}{section.12.5} {12.5.1}where}{154}{subsection.12.5.1} {12.6}函数}{156}{section.12.6} {12.7}组函数}{158}{section.12.7} {12.7.1}group by}{159}{subsection.12.7.1} {12.7.2}...

Global site tag (gtag.js) - Google Analytics