java - java.io.StreamCorruptedException:在子进程和父进程通信时写入子进程中的标准输出时流标头无效,ProcessBuilder
问题描述
我有一个代码段,其中创建了一个新的子进程,并且需要将一些新的进程操作结果从子进程发送到父进程。因此,我为子类的标准输出创建了一个新的 ObjectOutputStream,ObjectOutputStream stream = new ObjectOutputStream(System.out);
并将子进程中的对象序列化并发送到父进程,反序列化在父进程中完成。
它工作正常,没有任何问题。但是当我尝试System.out.println()
在子代码中使用它也写入标准输出时,问题就来了。父进程也尝试反序列化System.out.println()
,然后父进程中会有异常。
详细课程如下
public class DTO implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
public DTO()
{
this.name = "name";
}
public String getName() {
return name;
}
@Override
public int hashCode() {}
@Override
public boolean equals(Object obj) {}
父类.java
public class Parent {
public static void main(String[] args) {
try {
new Parent().start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void start() throws IOException, InterruptedException, ClassNotFoundException
{
String classpath = System.getProperty("java.class.path");
String className = Child.class.getCanonicalName();
ProcessBuilder builder = new ProcessBuilder(
"java", "-cp", classpath, className);
Process process = builder.start();
if (process.isAlive()) {
ObjectInputStream input = new ObjectInputStream(process.getInputStream());
DTO dto = (DTO)input.readObject();
}
}
}
子.java
public class Child {
public static void main(String[] args) throws IOException {
DTO dto = new DTO();
System.out.println("printing random text here");
ObjectOutputStream stream = new ObjectOutputStream(System.out);
stream.writeObject(dto);
stream.flush();
stream.close();
}
}
例外
java.io.StreamCorruptedException: invalid stream header: 64617364
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at working.Parent.start(Parent.java:35)
at working.Parent.main(Parent.java:14)
请注意,如果我们删除System.out.println()
child.java 中的 used,程序将执行而不会出错。我认为发生这种情况是因为序列化和sysout
都写入标准输出,父级认为它可以对两者进行反序列化。任何解决此问题的建议或执行此操作的不同类型的方法将不胜感激
解决方案
您通过直接向其写入字符串来破坏流。所以你有一个StreamCorruptedException
. 那里并不奇怪。你不能那样做。您不能反序列化还包含随机插值System.out.println()
的对象流。这应该是显而易见的。
任何解决此问题的建议
是的。不要这样做。
或替代方法
替代方法是什么?
您只需要决定您的System.out
用途。它要么是对象输出流,要么用于打印文本。不是同时两个。
请注意,正如我上次发布此代码时告诉您的那样,您仍然没有输入任何代码来读取错误流。如果没有错误检查,您将无法部署代码。
推荐阅读
- javascript - React UniversalRouter 防止用户离开页面
- python - python3:如何使用来自不同文件的相同类实例
- r - 从 Googlesheets 导入时,返回我无法在 R 中转换为日期的列表
- c++ - 如何强制 emscripten/em++/llvm 从 .rodata 加载常量和/或执行更好的 SIMD 优化?
- flutter - Flutter 找不到模块barcode_scan;
- .net - .net OWIN oauth2 AuthenticateCoreAsync() 在使用身份验证代码从提供商重定向后未被调用
- javascript - 如何将所有外部链接重定向到单独的免责声明页面并传递超链接?
- list - Dart 拆分/压缩列表
- azure - Azure API 管理转发请求不支持跟随重定向
- java - 如何在 Spring Data JPA 投影中处理 nullPointer