问题简述:
Java序列化的demo通常都是写到本地文件中的。但是,如果想要在内存中进行序列化,就会遇到异常:java.io.StreamCorruptedException: invalid stream header: EFBFBDEF。
问题代码:
@Nullable
public static Object readObject(@NonNull String objectString) {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(objectString.getBytes());
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(byteArrayInputStream);
return objectInputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
return null;
} finally {
if (objectInputStream != null) {
try {
objectInputStream.close();
} catch (IOException ignore) {
}
}
try {
byteArrayInputStream.close();
} catch (IOException ignore) {
}
}
}
@Nullable
public static String writeObject(@NonNull Object object) {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(bos);
oos.writeObject(object);
return bos.toString();
} catch (IOException e) {
return null;
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException ignore) {
}
}
}
}
解决方案:
@Nullable
public static Object readObject(@NonNull String objectString) {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(objectString.getBytes(StandardCharsets.ISO_8859_1));
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(byteArrayInputStream);
return objectInputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
return null;
} finally {
if (objectInputStream != null) {
try {
objectInputStream.close();
} catch (IOException ignore) {
}
}
try {
byteArrayInputStream.close();
} catch (IOException ignore) {
}
}
}
@Nullable
public static String writeObject(@NonNull Object object) {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(bos);
oos.writeObject(object);
return bos.toString(StandardCharsets.ISO_8859_1.name());
} catch (IOException e) {
return null;
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException ignore) {
}
}
}
}
方案简述:
遇到这个问题时,我网上搜索了一下,主要分为两种解决方案。
方案一:多进行一次转换,可见博客:Java字节数组序列化读取时异常的有效解决方案 java.io.StreamCorruptedException: invalid stream header: EFBFBDEF
方案二:使用base64。方案一博客中的评论有写。
本方案最大的好处就是代码简单,效率最高。需要注意的是StandardCharsets.ISO_8859_1
是Java 1.7才支持的。如果是Java 1.7以下,Java 1.4以上,可用Charset.forName("ISO-8859-1")
替换之。Java 1.4以下就不考虑。