首页 > 解决方案 > 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都写入标准输出,父级认为它可以对两者进行反序列化。任何解决此问题的建议或执行此操作的不同类型的方法将不胜感激

标签: javaioprocessbuilderobjectinputstream

解决方案


您通过直接向其写入字符串来破坏流。所以你有一个StreamCorruptedException. 那里并不奇怪。你不能那样做。您不能反序列化还包含随机插值System.out.println()的对象流。这应该是显而易见的。

任何解决此问题的建议

是的。不要这样做。

或替代方法

替代方法是什么?

您只需要决定您的System.out用途。它要么是对象输出流,要么用于打印文本。不是同时两个。

请注意,正如我上次发布此代码时告诉您的那样,您仍然没有输入任何代码来读取错误流。如果没有错误检查,您将无法部署代码。


推荐阅读