如何解决J2ME中文的乱码问题
Java的中文问题通常会困扰很多开发者,你可能在开发Web应用程序的时候遇到中文参数的传递问题,最后你可能选择使用Filter把Request的 编码方式设置为GBK来解决。在J2ME的开发中我们同样会遇到中文问题,比如在RMS中存储中文、网络传输中传输中文、从文件中读取中文等问题。
我们在解决中文问题的时候,用到的最多的一个词就是UTF-8。我们知道ASCII码是单字节编码方式,可以解决英文的问题,但是中文的字库 非常庞大,用ASSII码就难以解决了。Java语言是支持UNICODE编码方式的,UNICODE是双字节的编码方式可以支持中文字库,但是这多少带 来一些浪费,因为并不是所有的字符串都是非英文字符的。UTF-8编码方式正好可以解决这个问题,只有当字符不是ASSII码的时候他采用双字节来表示, 这样就节省了空间。这里我只总结了三种J2ME常见的中文问题。
网络传输中的中文问题
解决这个问题的关键是我们不采用InputStream或者OutputStream提供的方法按照字节来传递数据,而是把 InputStream或者OutputStream封装为DataInputStream和DataOutputStream。这样我们就可以使用 DataOutputStream中的writeUTF(String s)来送出数据了,同时可以使用DataInputStream提供的readUTF()来读入数据。注意在这两个方法搭配使用的时候要注意顺序。比如我 们在联网的时候可能写出这样的代码
客户端
dos.writeInt(myint);
dos.writeByte(mybyte);
dos.writeUTF(myString);
服务器端
int i = dis.readInt();
byte b = dis.readByte();
String s = dis.readUTF();
RMS持久性存储的中文问题
由于RMS中的数据存储都是按照byte[]的格式存储的,因此我们需要稍微变化一下,但是基本上还是走UTF-8的思路。
写入数据
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeUTF(myString);
byte[] data = baos.toByteArray();
rs.addRecord(data,0,data.length);
读出数据
byte[] data = rs.getRecord(index);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
DataInputStream dis = new DataInputStream(bais);
String myString = dis.readUTF();
读取中文文件的问题
在MIDP中并不支持文件系统,但是我们可以读取jar包中的文件。如果文件中含有中文,那么我们需要进行一些特殊的处理,首先我们使用UE 或者Notepad工具把相关的文件转换文UTF-8格式编码。我们在读取文件的时候需要进行如下的简单处理。下面是处理函数。
public String readFromFile(String fileName)
{
String returnString = null;
InputStream is = getClass().getResourceAsStream(fileName);
if (is != null)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int ch = 0;
try
{
while ((ch = is.read()) != -1)
{
baos.write(ch);
}
byte[] data = baos.toByteArray();
returnString = new String(data, "UTF-8");
is.close();
baos.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
return returnString;
}
我们在解决中文问题的时候,用到的最多的一个词就是UTF-8。我们知道ASCII码是单字节编码方式,可以解决英文的问题,但是中文的字库 非常庞大,用ASSII码就难以解决了。Java语言是支持UNICODE编码方式的,UNICODE是双字节的编码方式可以支持中文字库,但是这多少带 来一些浪费,因为并不是所有的字符串都是非英文字符的。UTF-8编码方式正好可以解决这个问题,只有当字符不是ASSII码的时候他采用双字节来表示, 这样就节省了空间。这里我只总结了三种J2ME常见的中文问题。
网络传输中的中文问题
解决这个问题的关键是我们不采用InputStream或者OutputStream提供的方法按照字节来传递数据,而是把 InputStream或者OutputStream封装为DataInputStream和DataOutputStream。这样我们就可以使用 DataOutputStream中的writeUTF(String s)来送出数据了,同时可以使用DataInputStream提供的readUTF()来读入数据。注意在这两个方法搭配使用的时候要注意顺序。比如我 们在联网的时候可能写出这样的代码
客户端
dos.writeInt(myint);
dos.writeByte(mybyte);
dos.writeUTF(myString);
服务器端
int i = dis.readInt();
byte b = dis.readByte();
String s = dis.readUTF();
RMS持久性存储的中文问题
由于RMS中的数据存储都是按照byte[]的格式存储的,因此我们需要稍微变化一下,但是基本上还是走UTF-8的思路。
写入数据
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeUTF(myString);
byte[] data = baos.toByteArray();
rs.addRecord(data,0,data.length);
读出数据
byte[] data = rs.getRecord(index);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
DataInputStream dis = new DataInputStream(bais);
String myString = dis.readUTF();
读取中文文件的问题
在MIDP中并不支持文件系统,但是我们可以读取jar包中的文件。如果文件中含有中文,那么我们需要进行一些特殊的处理,首先我们使用UE 或者Notepad工具把相关的文件转换文UTF-8格式编码。我们在读取文件的时候需要进行如下的简单处理。下面是处理函数。
public String readFromFile(String fileName)
{
String returnString = null;
InputStream is = getClass().getResourceAsStream(fileName);
if (is != null)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int ch = 0;
try
{
while ((ch = is.read()) != -1)
{
baos.write(ch);
}
byte[] data = baos.toByteArray();
returnString = new String(data, "UTF-8");
is.close();
baos.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
return returnString;
}