看到StreamCorruptedException抛出“原因”并指出“ 无效流头 ”,然后提供该无效流头的第一部分是相对常见的情况。 通常,确定异常原因的有用线索是了解无效流头是什么,因为这可以解释意外的原因并引起问题。
StreamCorruptedException只有两个构造函数, 一个不接受任何参数 , 一个接受单个描述异常原因的String 。 这告诉我们,“无效流头:XXXXXXXX”消息(其中XXXXXXXX表示各种无效的头详细信息)由实例化(并可能抛出)这些StreamCorruptedException
的代码提供,而不是由该异常类本身提供。 这意味着,遇到这些异常之一时,不一定总是遇到相同格式的消息,但是在大多数情况下,格式与“ invalid stream header:”无效,后跟该无效流头的第一部分。
通常由ObjectInputStream抛出此异常。 该类的Javadoc包含一些有用的详细信息,有助于解释为什么遇到“ StreamCorruptedException:invalid stream header ”。 类级别的Javadoc指出:“只能从流中读取支持java.io.Serializable或java.io.Externalizable接口的对象。” ObjectInputStream(InputStream)构造函数的Javadoc声明(我强调说 ) ``创建一个从指定InputStream读取的ObjectInputStream 。 从流中读取并验证序列化流头 。”
正如引用的Javadoc所解释的, ObjectInputStream
应该与序列化数据一起使用。 当文本文件(例如HTML,XML,JSON等)传递给此构造函数而不是Java序列化文件时,会发生“ StreamCorruptedException:无效的流头”消息的许多情况。
以下是从与StreamCorruptedException
相关联的“无效流头”消息派生并在线报告的“ ASCII”值示例。
无效的流头值(HEX) | 对应的整数 | 相应 “ ASCII”值 | 在线参考/示例 |
---|---|---|---|
00000000 | 000 000 000 000 | https://stackoverflow.com/questions/44479323/exception-in-thread-main-java-io-streamcorruptedexception-invalid-stream-head | |
0A0A0A0A | 010010010010 | https://issues.jenkins-ci.org/browse/JENKINS-35197 | |
0A0A3C68 | 010010060104 | <h | https://developer.ibm.com/answers/questions/201983/what-does-javaiostreamcorruptedexception-invalid-s/ |
20646520 | 032100101032 | 德 | https://stackoverflow.com/questions/2622716/java-invalid-stream-header-problem |
30313031 | 048 049 048 049 | 0101 | https://stackoverflow.com/questions/48946230/java-io-streamcorruptedexception-invalid-stream-header-30313031 |
32303138 | 050 048 049 056 | 2018年 | https://stackoverflow.com/questions/49878481/jpa-invalid-stream-header-32303138 |
3C21444F | 060 033 068 079 | <!DO | https://github.com/metasfresh/metasfresh/issues/1335 |
3c48544d | 060 072 084 077 | <HTM | http://forum.spring.io/forum/spring-projects/integration/jms/70353-java-io-streamcorruptedexception-invalid-stream-header |
3C6F626A | 060111098106 | <obj | |
3C787364 | 060120115100 | <xsd | https://stackoverflow.com/questions/29769191/java-io-streamcorruptedexception-invalid-stream-header-3c787364 |
41434544 | 065 067 069 068 | ACED | https://stackoverflow.com/questions/36677022/java-io-streamcorruptedexception-invalid-stream-header-41434544 |
48656C6C | 072 101 108 108 | 地狱 | https://stackoverflow.com/questions/28298366/java-io-streamcorruptedexception-invalid-stream-header-48656c6c |
4920616D | 073 032 097 109 | 我是 | https://stackoverflow.com/questions/34435188/java-io-streamcorruptedexception-invalid-stream-header-4920616d |
54656D70 | 084 101109112 | 温度 | https://stackoverflow.com/a/50669243 |
54657374 | 084 101115116 | 测试 | java.io.StreamCorruptedException:无效的流头:54657374 |
54686973 | 084 104105115 | 这个 | https://stackoverflow.com/questions/28354180/stanford-corenlp-streamcorruptedexception-invalid-stream-header-54686973 |
64617364 | 100097115100 | s | https://stackoverflow.com/questions/50451100/java-io-streamcorruptedexception-invalid-stream-header-when-writing-to-the-stdo?noredirect=1&lq=1 |
70707070 | 112112112112 | pppp | https://stackoverflow.com/questions/32858472/java-io-streamcorruptedexception-invalid-stream-header-70707070 |
72657175 | 114101113117 | 要求 | https://stackoverflow.com/questions/8534124/java-io-streamcorruptedexception-invalid-stream-header-72657175 |
7371007E | 115113 000126 | 平方〜 | https://stackoverflow.com/questions/2939073/java-io-streamcorruptedexception-invalid-stream-header-7371007e |
77617161 | 119097113097 | 瓦卡 | https://coderanch.com/t/278717/java/StreamCorruptedException-invalid-stream-header |
7B227061 | 123034112097 | {“ pa | https://stackoverflow.com/questions/9986672/streamcorruptedexception-invalid-stream-header |
上面的示例显示了“ StreamCorruptedException:无效流头”消息,该消息发生在表示文本的输入流传递给期望Java序列化格式的构造函数的情况下。 突出显示的行特别有趣。 该条目(“ ASCII”字符表示形式的“ ACED ”)看起来像通过Java的默认序列化序列化的所有文件中所期望的一样,但这并不完全正确。
Java Object Serialization Specification的“ Terminal Symbols and Constants ”部分告诉我们, java.io.ObjectStreamConstants定义了一个常量STREAM_MAGIC ,它是“写入流头的幻数”。 该规范进一步解释了ObjectStreamConstants.STREAM_MAGIC
被定义为(short)0xaced
并且可以根据需要在Java代码中进行验证。 特定条目导致错误的原因是它应该是“ ACED”的十六进制表示,而不是转换后的“ ASCII”字符表示。 换句话说,对于该特定情况,实际上是文字文本“ ACED”在前一个字节中,而不是十六进制“ ACED”表示形式所表示的字节。
有多种方法可以转换“ StreamCorruptedException:无效流头”消息中提供的十六进制表示,以查看其是否转换为表示某些含义的文本。 如果它是文本,则知道他或她已经处于一个糟糕的开端,因为应该使用二进制序列化文件代替文本。 该文本中的字符可以提供有关意外提供哪种类型的文本文件的进一步线索。 这是使用Java( 可在GitHub上 )将提供的十六进制表示形式转换为“ ASCII”文本的一种方法:
private static String toAscii(final String hexInput)
{final int length = hexInput.length();final StringBuilder ascii = new StringBuilder();final StringBuilder integers = new StringBuilder();for (int i = 0; i < length; i+=2){final String twoDigitHex = hexInput.substring(i, i+2);final int integer = Integer.parseInt(twoDigitHex, 16);ascii.append((char)integer);integers.append(String.format("%03d", integer)).append(" ");}return hexInput + " ==> " + integers.deleteCharAt(integers.length()-1).toString() + " ==> " + ascii.toString();
}
文本流不经意传递给ObjectInputStream
的构造方法不是“ StreamCorruptedException:无效的流头”的唯一原因。 实际上,任何不以预期的“流魔术”字节( 0xaced
)开头的InputStream
(文本或二进制)都将导致此异常。
翻译自: https://www.javacodegeeks.com/2019/01/value-streamcorruptedexception-invalid-stream.html