【请教】使用ObjectInputStream的readObject无法读出带有中文的对象

jsjszg 2012-02-19 12:45:21
我使用ObjectOutputStream(new ByteArrayOutputStream()).writeObject将一个JavaBean对象写入一个字符串content,
然后使用ObjectInputStream(new ByteArrayInputStream(content.getBytes())).readObject()却读不出来。
并且跑出异常:
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2279)


最后发现必须指定编码格式为ISO-8859-1才行(其他编码不行,比如GBK、UTF-8)。但是不知道什么原因。
难道writeObject是按照ISO-8859-1编码写入字节流的吗?是否可以指定编码格式呢?


问题代码:



//将对象写入字符串
public static String serialzeToString(Object o){
ObjectOutputStream os = null;
try{
ByteArrayOutputStream bs = new ByteArrayOutputStream();
os = new ObjectOutputStream(bs);
os.writeObject(o);
byte[] bytes = bs.toByteArray();
String retStr = new String(bytes);
return retStr;
}catch(Exception e){
e.printStackTrace();
return null;
}
}



//从字符串中读取出对象
public static Object derialzeFromString(String content){
ObjectInputStream ois = null;
try{
byte[] bytes = content.getBytes();
ByteArrayInputStream bs = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bs);
Object o = ois.readObject();
return o;
}catch(Exception e){
e.printStackTrace();
return null;
}
}


按照ISO-8850-1编解码就可以了
修改后的代码:

//将对象写入字符串
public static String serialzeToString(Object o){
ObjectOutputStream os = null;
try{
ByteArrayOutputStream bs = new ByteArrayOutputStream();
os = new ObjectOutputStream(bs);
os.writeObject(o);
byte[] bytes = bs.toByteArray();
String retStr = new String(bytes,"ISO-8859-1"); //按照ISO-8859-1解码
return retStr;
}catch(Exception e){
e.printStackTrace();
return null;
}
}



//从字符串中读取出对象
public static Object derialzeFromString(String content){
ObjectInputStream ois = null;
try{
byte[] bytes = content.getBytes("ISO-8859-1");//按照ISO-8859-1编码
ByteArrayInputStream bs = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bs);
Object o = ois.readObject();
return o;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
...全文
528 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
jsjszg 2012-02-19
  • 打赏
  • 举报
回复
问题是数据库类型几年前早已经定好的,此功能为新增功能,不可能修改。
MiceRice 2012-02-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 jsjszg 的回复:]
我是把树结构的对象序列化后存放到数据库,为后续加载用。数据库中以字符串形式存放的。
[/Quote]

可以直接用 blob 类型,反正无论存进去的是String还是二进制还是BASE64后的东西,你肉眼都看不懂。
jsjszg 2012-02-19
  • 打赏
  • 举报
回复
大概明白了。
我是把树结构的对象序列化后存放到数据库,为后续加载用。数据库中以字符串形式存放的。


[Quote=引用 7 楼 ldh911 的回复:]
楼主,一般来说如果是文件操作或者是网络传输,根本不会转换为String,直接把byte[]数组完整写进文件就完了。如果你实在是非常非常希望能变成String,那么就BASE64编码,这才是国际通用做法。
[/Quote]
MiceRice 2012-02-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 jsjszg 的回复:]
为什么其他编码不合适呢?比如GBK、UTF-8.所以我觉得是不是ObjectOutputStream在写入时将对象中的中文以ISO-8859-1编码成了字节流呢?
[/Quote]

不是。因为GBK和UTF-8都是大字符集(多byte才构成一个char),编码都是有对照关系的。

比如你的byte恰好出现 [255][255],那么根本从GBK中根本找不到一个汉字的字节码是[255][255],必然完蛋。

但ISO-8859-1是单字符集(一个byte就是一个char),所以从[0]~[255]都能找到对应的字符(char)。



楼主,一般来说如果是文件操作或者是网络传输,根本不会转换为String,直接把byte[]数组完整写进文件就完了。如果你实在是非常非常希望能变成String,那么就BASE64编码,这才是国际通用做法。
jsjszg 2012-02-19
  • 打赏
  • 举报
回复
为什么其他编码不合适呢?比如GBK、UTF-8.所以我觉得是不是ObjectOutputStream在写入时将对象中的中文以ISO-8859-1编码成了字节流呢?

[Quote=引用 3 楼 ldh911 的回复:]

楼主,你的问题并不是出在readObject或者writeObject的问题;而是你想把byte[]转成String来传输或存储。

而byte[]转换为String,才会存在编码问题;因为这种情况下Java会试图把byte数组去跟字符集做映射,对照时出错是很正常的。

不信的话,你可以把byte[]直接用BASE64编码为String,一样能解决问题。
[/Quote]

limeng1311 2012-02-19
  • 打赏
  • 举报
回复
用try语句捕获
jsjszg 2012-02-19
  • 打赏
  • 举报
回复
问题补充:
没有写入文件,就是把对象写入字符串,然后再从字符串中读取出来。

测试代码:


public class SerializeDemo {

private static void testPerson(Person p){
String str = SerializableTool.serialzeToString(p);
Person p2 = (Person)SerializableTool.derialzeFromString(str);
}

public static void main(String[] args) {
Person me = new Person(2,"abcd我1234",Gender.Male);
testPerson(me);
}
}



import java.io.Serializable;

public class Person implements Serializable {
private static final long serialVersionUID = 1L;

public enum Gender{
Male, Femal;
}

private int id;
private String name;
private Gender gender;

public Person(){}
public Person(int id,String name,Gender gender){
this.id = id;
this.name = name;
this.gender = gender;
}

public int getId() {
return id;
}


public void setId(int id) {
this.id = id;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


public Gender getGender() {
return gender;
}


public void setGender(Gender gender) {
this.gender = gender;
}
}
MiceRice 2012-02-19
  • 打赏
  • 举报
回复
楼主,你的问题并不是出在readObject或者writeObject的问题;而是你想把byte[]转成String来传输或存储。

而byte[]转换为String,才会存在编码问题;因为这种情况下Java会试图把byte数组去跟字符集做映射,对照时出错是很正常的。

不信的话,你可以把byte[]直接用BASE64编码为String,一样能解决问题。
wuxiaoke2009 2012-02-19
  • 打赏
  • 举报
回复
学习了哈!!!
chenshj20111024 2012-02-19
  • 打赏
  • 举报
回复
是不是写入文件的编码有问题呢?应该给写入文件指定编码

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧