使用 ObjectInputStream 等待来自套接字的数据
我正在以一种奇怪的方式等待流上的数据...因为我认为每次流尝试 readObject()
时抛出异常不是一个好主意。这就是为什么我使用 PushBackInputStream
并每 10 毫秒从该流中读取一个 字节
。
@Override
public void run() {
try {
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(
clientSocket.getOutputStream()));
oos.flush();
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
PushbackInputStream pis = new PushbackInputStream(clientSocket.getInputStream());
while (true) {
int tempByte = -1;
if ((tempByte = pis.read()) == -1) {
sleep(10);
} else {
pis.unread(tempByte);
ArrayList<Object> arrList = (ArrayList<Object>) ois.readObject();
int command = (Integer) arrList.get(0);
if (command == CommandDescriptor.ADD_STRING.getCode()) {
String tempStr = (String) arrList.get(1);
boolean result = Server.colleciton.add(tempStr);
if (result) {
oos.writeInt(1);
oos.flush();
} else {
oos.writeInt(0);
oos.flush();
}
} else if (command == CommandDescriptor.REMOVE_STRING.getCode()) {
...
我对流做了一些错误...我得到一个异常:
Exception in thread "Thread-0" java.lang.ClassCastException: java.io.ObjectStreamClass cannot be cast to java.util.ArrayList
at com.rizhov.main.ClientHandler.run(ClientHandler.java:39)
在代码的那部分:
ArrayList<Object> arrList = (ArrayList<Object>) ois.readObject();
我做错了什么?有没有更好的解决办法等待数据。
更新:
ArrayList<Object> arrList = null;
for (;;) {
try {
arrList = ((ArrayList<Object>) ois.readObject());
break;
} catch (Exception e) {
}
}
int command = (Integer) arrList.get(0);
I'm waiting for the data on the stream such a strange way... Because i think throwing exceptions each time stream tries readObject()
is not a good idea. That's why I use PushBackInputStream
and read just one byte
from that stream each 10 ms.
@Override
public void run() {
try {
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(
clientSocket.getOutputStream()));
oos.flush();
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
PushbackInputStream pis = new PushbackInputStream(clientSocket.getInputStream());
while (true) {
int tempByte = -1;
if ((tempByte = pis.read()) == -1) {
sleep(10);
} else {
pis.unread(tempByte);
ArrayList<Object> arrList = (ArrayList<Object>) ois.readObject();
int command = (Integer) arrList.get(0);
if (command == CommandDescriptor.ADD_STRING.getCode()) {
String tempStr = (String) arrList.get(1);
boolean result = Server.colleciton.add(tempStr);
if (result) {
oos.writeInt(1);
oos.flush();
} else {
oos.writeInt(0);
oos.flush();
}
} else if (command == CommandDescriptor.REMOVE_STRING.getCode()) {
...
I do something wrong with streams... I get an exception:
Exception in thread "Thread-0" java.lang.ClassCastException: java.io.ObjectStreamClass cannot be cast to java.util.ArrayList
at com.rizhov.main.ClientHandler.run(ClientHandler.java:39)
At that part of code:
ArrayList<Object> arrList = (ArrayList<Object>) ois.readObject();
What am I doing wrong? Is there any better solution to wait a data.
UPDATE:
ArrayList<Object> arrList = null;
for (;;) {
try {
arrList = ((ArrayList<Object>) ois.readObject());
break;
} catch (Exception e) {
}
}
int command = (Integer) arrList.get(0);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没有必要偷看和睡觉。这完全是浪费你的时间和精力以及CPU时间和空间。
当没有数据时,所有 Java 流都会阻塞。它们阻塞的时间也完全正确,一次不是 10 毫秒或其他任何时间,并且不会像您所做的那样在旋转中浪费 CPU 周期。
您不必以任何方式或形式亲自做任何事情。只需调用
readObject()
即可。并且永远不要忽略
IOException
。There is no need for any of this peeking and sleeping. It is a complete waste of your time and energy and of CPU time and space.
All Java streams block while there is no data. They block for exactly the correct amount of time, too, not 10ms or whatever at a time, and without wasting CPU cycles in spinning as you are doing.
You don't have to do any of that yourself in any way shape or form. Just call
readObject()
.And never ignore an
IOException
.您只能对 Stream 进行一次包装。如果你多次包装它,你很可能会感到困惑,而不是它的用处。
一旦流关闭,它就不会重新打开,因此读取字符来检查流是否已完成并丢弃它并不是很有用。当操作无论如何都会阻塞时休眠也不是很有用。
我不会使用
Integer
代码,而是使用枚举值。这会更干净,您将能够使用 switch 语句。You can only wrap a Stream once. If you wrap it multiple times you are more likely to get confused than it be useful.
Once a stream has closed it won't re-open so reading a character to check if the stream has finished and discarding it is not very useful. Sleeping when the operation would block anyway is not very useful either.
Instead of using
Integer
codes I would use enum values. This will be cleaner and you will be able to use a switch statement.