如何修复 ObjectInputStream 和 ObjectOutputStream 的 "write end dead" 和 "read end dead" 错误?
How can I fix my "write end dead" and "read end dead" errors for ObjectInputStream and ObjectOutputStream?
这是my question here的一种扩展。
我有 3 个 classes.
我的主要:
import java.io.*;
public class ConnectionManager {
public static void main(String argv[]) {
try {
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
Sender s = new Sender(pout,true);
Receiver r = new Receiver(pin,true);
System.out.println("Starting threads");
s.start();
r.start();
} catch (Exception e) {System.out.println(e);}
}
}
我的Sender/Producerclass:
import java.io.*;
public class Sender extends Thread {
ObjectOutputStream oos;
boolean primitive;
public Sender(OutputStream os, boolean primitive) {
try {
oos = new ObjectOutputStream(os);
this.primitive = primitive;
} catch (Exception e) {System.out.println(e);}
}
public void run() {
try {
System.out.println("Sending a message");
Thread.sleep(1000);
oos.writeInt(99);
oos.flush();
System.out.println("Message sent, terminating");
oos.close();
} catch (Exception e) {System.out.println("Sender: " + e);}
}
}
我的Receiver/Consumerclass:
import java.io.*;
public class Receiver extends Thread {
ObjectInputStream ois;
boolean primitive;
public Receiver(InputStream is, boolean primitive) {
try {
ois = new ObjectInputStream(is);
this.primitive = primitive;
} catch (Exception e) {System.out.println(e);}
}
public void run() {
try {
System.out.println("waiting for a message");
int x = ois.readInt();
System.out.println("message received: " + x);
ois.close();
} catch (Exception e) {System.out.println("Receiver: " + e);}
}
}
产生这个输出:
Starting threads
Sending a message
waiting for a message
Receiver: java.io.IOException: Write end dead
Sender: java.io.IOException: Read end dead
我在 this page 中读到,我收到这些异常是因为我没有关闭管道。但即使我这样做了,我仍然得到它们。我该如何解决这个问题?
编辑:我将流对象的类型从 PipedInputStream 转换为 InputStream 然后使用 InputStream 构造一个新的 ObjectInputStream 的原因是因为我希望能够发送和接收各种类型的数据,不只是 int 或字节。
我保持纠正;并遵循 EJP 的建议;这是一个可行的解决方案。
import java.io.*;
public class ConnectionManager {
public static void main(String argv[]) throws Exception {
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
Sender s = new Sender(pout);
Receiver r = new Receiver(pin);
System.out.println("Starting threads");
s.start();
r.start();
}
}
class Sender extends Thread {
private final OutputStream os;
Sender(OutputStream os) { this.os = os; }
public void run() {
try(ObjectOutputStream oos = new ObjectOutputStream(os)) {
oos.writeInt(99);
System.out.println("Message sent, terminating");
} catch (Exception e) {
System.out.println("Sender: " + e);
e.printStackTrace();
}
}
}
class Receiver extends Thread {
private final InputStream is;
Receiver(InputStream is) {this.is = is; }
public void run() {
try(ObjectInputStream ois = new ObjectInputStream(is)) {
System.out.println("waiting for a message");
int x = ois.readInt();
System.out.println("message received: " + x);
} catch (Exception e) {
System.out.println("Receiver: " + e);
e.printStackTrace();
}
}
}
应该打印:
Starting threads
Message sent, terminating
waiting for a message
message received: 99
注意:核心点是在运行方法中创建ObjectInputStreams。除此之外:删除了不必要的东西(那个布尔原语;但添加了 try-with-resources 和打印堆栈跟踪)。
这些错误不是来自对象流。查看堆栈跟踪。它们来自管道流,它们的发生是因为相关线程已经退出或尚未启动。而这样做的原因又是因为您是在线程构造函数中而不是在 run()
方法中构造对象流,并且两个对象流构造函数都执行 I/O,并且您还没有启动线程了。
你不需要睡觉。
不要为此使用管道。使用队列。
注意你的评论,你不需要将 PipedInputStream
转换为 InputStream
。已经是了。事实上你不是。
这是my question here的一种扩展。
我有 3 个 classes.
我的主要:
import java.io.*;
public class ConnectionManager {
public static void main(String argv[]) {
try {
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
Sender s = new Sender(pout,true);
Receiver r = new Receiver(pin,true);
System.out.println("Starting threads");
s.start();
r.start();
} catch (Exception e) {System.out.println(e);}
}
}
我的Sender/Producerclass:
import java.io.*;
public class Sender extends Thread {
ObjectOutputStream oos;
boolean primitive;
public Sender(OutputStream os, boolean primitive) {
try {
oos = new ObjectOutputStream(os);
this.primitive = primitive;
} catch (Exception e) {System.out.println(e);}
}
public void run() {
try {
System.out.println("Sending a message");
Thread.sleep(1000);
oos.writeInt(99);
oos.flush();
System.out.println("Message sent, terminating");
oos.close();
} catch (Exception e) {System.out.println("Sender: " + e);}
}
}
我的Receiver/Consumerclass:
import java.io.*;
public class Receiver extends Thread {
ObjectInputStream ois;
boolean primitive;
public Receiver(InputStream is, boolean primitive) {
try {
ois = new ObjectInputStream(is);
this.primitive = primitive;
} catch (Exception e) {System.out.println(e);}
}
public void run() {
try {
System.out.println("waiting for a message");
int x = ois.readInt();
System.out.println("message received: " + x);
ois.close();
} catch (Exception e) {System.out.println("Receiver: " + e);}
}
}
产生这个输出:
Starting threads
Sending a message
waiting for a message
Receiver: java.io.IOException: Write end dead
Sender: java.io.IOException: Read end dead
我在 this page 中读到,我收到这些异常是因为我没有关闭管道。但即使我这样做了,我仍然得到它们。我该如何解决这个问题?
编辑:我将流对象的类型从 PipedInputStream 转换为 InputStream 然后使用 InputStream 构造一个新的 ObjectInputStream 的原因是因为我希望能够发送和接收各种类型的数据,不只是 int 或字节。
我保持纠正;并遵循 EJP 的建议;这是一个可行的解决方案。
import java.io.*;
public class ConnectionManager {
public static void main(String argv[]) throws Exception {
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
Sender s = new Sender(pout);
Receiver r = new Receiver(pin);
System.out.println("Starting threads");
s.start();
r.start();
}
}
class Sender extends Thread {
private final OutputStream os;
Sender(OutputStream os) { this.os = os; }
public void run() {
try(ObjectOutputStream oos = new ObjectOutputStream(os)) {
oos.writeInt(99);
System.out.println("Message sent, terminating");
} catch (Exception e) {
System.out.println("Sender: " + e);
e.printStackTrace();
}
}
}
class Receiver extends Thread {
private final InputStream is;
Receiver(InputStream is) {this.is = is; }
public void run() {
try(ObjectInputStream ois = new ObjectInputStream(is)) {
System.out.println("waiting for a message");
int x = ois.readInt();
System.out.println("message received: " + x);
} catch (Exception e) {
System.out.println("Receiver: " + e);
e.printStackTrace();
}
}
}
应该打印:
Starting threads
Message sent, terminating
waiting for a message
message received: 99
注意:核心点是在运行方法中创建ObjectInputStreams。除此之外:删除了不必要的东西(那个布尔原语;但添加了 try-with-resources 和打印堆栈跟踪)。
这些错误不是来自对象流。查看堆栈跟踪。它们来自管道流,它们的发生是因为相关线程已经退出或尚未启动。而这样做的原因又是因为您是在线程构造函数中而不是在 run()
方法中构造对象流,并且两个对象流构造函数都执行 I/O,并且您还没有启动线程了。
你不需要睡觉。
不要为此使用管道。使用队列。
注意你的评论,你不需要将 PipedInputStream
转换为 InputStream
。已经是了。事实上你不是。