[Exception]java.io.StreamCorruptedException: invalid stream header
今天在做模型序列化保存的时候出现这个异常,首先给大家介绍一下场景。我在Spark-mllib的环境下将训练好的模型序列化,并且将序列化的Byte数组存入数据库。但是在从数据库中读取出Byte数组后,反序列化的过程中弹出这个异常。
异常定位的代码如下:
*** val reloadedModel: KMeansModel = reloadModel("kmeans")
def reloadModel(modelName: String): KMeansModel = {
val utils: DMUtils = new DMUtils()
val conn: Connection = utils.getConnection
var sql = "select * from kmeansmodel3 where modelName='kmeans';"
val pstmt: PreparedStatement = conn.prepareStatement(sql)
var model: KMeansModel = null
try {
val set: ResultSet = pstmt.executeQuery()
while (set.next()) {
//val modelName: String = set.getString(1)
val bytes: Array[Byte] = set.getBytes(3)
bytes.foreach(print(_))
*** model = bytesArray2Model(bytes)
}
} catch {
case ex: Exception => {}
println("select model operation fail ...")
ex.printStackTrace()
} finally {
// 释放资源
pstmt.close()
conn.close()
}
model
}
def bytesArray2Model(bytesArray: Array[Byte]) = {
var bais: ByteArrayInputStream = null
var ois: ObjectInputStream = null
var model: KMeansModel = null
try {
bais = new ByteArrayInputStream(bytesArray)
*** ois = new ObjectInputStream(bais)
model = ois.readObject().asInstanceOf[KMeansModel]
} catch {
case ex: Exception => {
println("deserialize fail ...")
ex.printStackTrace()
}
} finally {
ois.close()
bais.close()
}
model
}
出问题的语句我使用***来标注,可以看到最终定位在ois = new ObjectInputStream(bais)
,显然反序列化出了问题。
思路:首先,我搜索了大量scala序列化和反序列化的操作案例,发现我的操作与博客的做法并无太大区别,唯一的区别就是我经过了数据库的IO,所以可以考虑是数据库IO过程中出了问题。然后,我写了一个小案例来测试是否是因为模型的原因序列化出问题,但是结果是成功反序列化了,那么问题就可以定位在数据库。接下来,我将序列化前与反序列化后的Byte数组做了打印,发现结果不一致,那么一定就是IO出了问题。最后,我在所使用的数据库的程序员手册中找到了正确类型,修改表结构,成功通过反序列化。