为何无法用ObjectInputStream包装FileInputStream读取二进制文件对象?
问题分析与解决
错误原因
你代码里的核心问题是读写方法不匹配:
- 写入时用了
ObjectOutputStream.write(byte[]),这个方法属于父类OutputStream,作用是直接把字节数组的原始内容写入文件,没有按照Java对象序列化的格式添加类型标识、对象头等必要信息。 - 但读取时用了
ObjectInputStream.readObject(),这个方法是专门用来读取完整序列化后的Java对象的,它会期望文件里有符合序列化规范的数据结构,因此读取原始字节流时会抛出异常。
两种修正方案
方案一:使用普通流读写(更适合纯字节场景)
既然你只是读写原始字节,没必要用Object流,直接用基础的FileInputStream/FileOutputStream即可:
import java.io.*; import java.net.URL; public class JavaApplication { public static void main(String[] args) throws IOException { URL u = new URL("https://www.javatpoint.com/java-string-valueof"); byte[] bytes = u.openStream().readAllBytes(); // 写入原始字节 try (FileOutputStream output = new FileOutputStream("binary.dat")) { output.write(bytes); } // 读取原始字节 try (FileInputStream input = new FileInputStream("binary.dat")) { byte[] byte1 = input.readAllBytes(); for (byte b : byte1) { System.out.println(String.valueOf(b)); } } catch (Exception e) { System.out.println(e); } } }
方案二:正确使用对象序列化
如果一定要用Object流,需要用writeObject()方法来序列化字节数组对象,这样读取时readObject()才能正确识别:
import java.io.*; import java.net.URL; public class JavaApplication { public static void main(String[] args) throws IOException { URL u = new URL("https://www.javatpoint.com/java-string-valueof"); byte[] bytes = u.openStream().readAllBytes(); // 序列化字节数组对象写入 try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("binary.dat"))) { output.writeObject(bytes); // 注意这里用writeObject而不是write } // 反序列化读取 try (ObjectInputStream input = new ObjectInputStream(new FileInputStream("binary.dat"))) { byte[] byte1 = (byte[]) input.readObject(); for (byte b : byte1) { System.out.println(String.valueOf(b)); } } catch (Exception e) { System.out.println(e); } } }
额外建议
代码里手动关闭流容易出现资源泄漏,推荐使用try-with-resources语法(如上面代码所示),它会自动在代码块结束时关闭实现了AutoCloseable接口的资源,更安全简洁。
内容的提问来源于stack exchange,提问作者Li's hideout
相关产品推荐
相关产品推荐

