utf 8 Java字符问题修复,但希望了解错误数据是如何生成的
试图在Oracle表中插入这样的字符串:ABčDE
Oracle表的定义如下:
SQL> create table DUMMY_TEST (Field1 number, Name_Test varchar2(20));
下面是正在使用的Java/JDBC代码。它有两个插入。 一个Insert硬编码到代码中,第二个Insert从文件中检索
import java.sql.*;
import java.util.*;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Locale;
class JdbcTest
{
static StringBuffer sbuff = new StringBuffer();
public static void main (String a[])
{
//Creating the connection
String url = "jdbc:oracle:thin:@//server:port/ServiceName";
String user = "xa21appdb";
String pass = "neptune";
//Inserting data using SQL query
String sql = "INSERT INTO DUMMY_TEST VALUES(1, 'ABèDE')";
loadDataFromFile();
Connection con=null;
try
{
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
//Reference to connection interface
con = DriverManager.getConnection(url,user,pass);
Statement st = con.createStatement();
System.out.println("Executing 1st INSERT");
int m = st.executeUpdate(sql);
if (m == 1)
System.out.println("1st inserted successfully ");
else
System.out.println("1st insertion failed");
System.out.println("Executing 2nd INSERT");
m = st.executeUpdate(sbuff.toString());
if (m == 1)
System.out.println("2nd inserted successfully ");
else
System.out.println("2nd insertion failed");
con.close();
}
catch(Exception ex)
{
System.err.println(ex);
}
}
static void loadDataFromFile()
{
try
{
InputStream inputStream = new FileInputStream("/tmp/input.txt");
Reader inputStreamReader = new InputStreamReader( inputStream, "UTF-8");
int ch = inputStreamReader.read();
while(ch != -1)
{
sbuff.append((char) ch);
ch = inputStreamReader.read();
}
inputStreamReader.close();
}
catch(Exception e){}
}
}
以下是文件的内容,其中包含与硬编码值相同的SQL
> cat /tmp/input.txt
INSERT INTO DUMMY_TEST VALUES(2, 'ABèDE')
为了确保硬编码SQL和文件中的SQL相同,使用xxd命令显示十六进制值
这仅显示INSERT语句以及要插入的ABčDE字符串
> xxd -b JdbcTest.java
:
:
000019e: 01101100 00100000 00111101 00100000 00100010 01001001 l = "I
00001a4: 01001110 01010011 01000101 01010010 01010100 00100000 NSERT
00001aa: 01001001 01001110 01010100 01001111 00100000 01000100 INTO D
00001b0: 01010101 01001101 01001101 01011001 01011111 01010100 UMMY_T
00001b6: 01000101 01010011 01010100 00100000 01010110 01000001 EST VA
00001bc: 01001100 01010101 01000101 01010011 00101000 00110001 LUES(1
00001c2: 00101100 00100000 00100111 01000001 01000010 11101000 , 'AB.
00001c8: 01000100 01000101 00100111 00101001 00100010 00111011 DE')";
这显示了使用要插入的ABčDE字符串读取的整个文件代码
> xxd -b /tmp/input.txt
0000000: 01001001 01001110 01010011 01000101 01010010 01010100 INSERT
0000006: 00100000 01001001 01001110 01010100 01001111 00100000 INTO
000000c: 01000100 01010101 01001101 01001101 01011001 01011111 DUMMY_
0000012: 01010100 01000101 01010011 01010100 00100000 01010110 TEST V
0000018: 01000001 01001100 01010101 01000101 01010011 00101000 ALUES(
000001e: 00110010 00101100 00100000 00100111 01000001 01000010 2, 'AB
0000024: 11101000 01000100 01000101 00100111 00101001 00001010 .DE').
比较2文件时,确认硬代码和文件之间的字符串相同
00100111 01000001 01000010 11101000 01000100 01000101 00100111
' A B . D E '
运行代码时,将以下两行插入到Oracle中
SQL> select * from dummy_test;
FIELD1 NAME_TEST
---------- --------------------
1 ABèDE
2 AB?DE
使用DUMP命令获取每个的详细信息
SQL> select field1, dump(name_test, 1016) from dummy_test;
FIELD1 DUMP(NAME_TEST,1016)
---------- -------------------------------------------------------------
1 Typ=1 Len=6 CharacterSet=AL32UTF8: 41,42,c4,8d,44,45
2 Typ=1 Len=7 CharacterSet=AL32UTF8: 41,42,ef,bf,bd,44,45
如果代码是根据此修改的:
Reader inputStreamReader = new InputStreamReader( inputStream, "UTF-8");
为此:
Reader inputStreamReader = new InputStreamReader( inputStream);
这两行都将显示以下内容:
SQL> select field1, dump(name_test, 1016) from dummy_test;
FIELD1 DUMP(NAME_TEST,1016)
---------- -------------------------------------------------------------
1 Typ=1 Len=6 CharacterSet=AL32UTF8: 41,42,c4,8d,44,45
2 Typ=1 Len=6 CharacterSet=AL32UTF8: 41,42,c4,8d,44,45
现在回答3个问题
1-在这种情况下,当它工作并且正确插入“特殊”字符时,这可以得到确认,因为Oracle字符集AL32UTF8显示c4 8d代表č,但我的问题是Oracle为什么打印č
2-当UTF-8与读卡器一起使用时,将插入3个字节(ef、bf、bd)。 如果我正确地进行UTF-8计算,结果如下:
11101111 10111111 10111101
1111111111111101
FF FD
这是一个非常不寻常的角色
虽然我知道这与转换有冲突,但你能准确解释发生了什么吗
编辑以添加第三个问题
3-My Putty session的字符集设置为:ISO-8859-1:1998(拉丁语-1,西欧) 为什么在命令提示符下看到的是ABèDE而不是ABčDE
共 (0) 个答案