0

私はストリーム上のデータをとても奇妙な方法で待っています...ストリームが試行するたびに例外をスローreadObject()するのは良い考えではないと思うからです。そのため、10 ミリ秒ごとにそのストリームから1 つだけを使用PushBackInputStreamして読み取ります。byte

@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);
4

2 に答える 2

2

こののぞき見や睡眠の必要はありません。これは、時間とエネルギー、および CPU の時間とスペースを完全に無駄にします。

データがない間、すべての Java ストリームがブロックされます。それらは、一度に 10 ミリ秒などではなく、正確に正しい時間ブロックし、実行中のスピンで CPU サイクルを浪費することもありません。

形や形を問わず、自分で行う必要はありません。呼び出すだけreadObject()です。

を決して無視しないでIOExceptionください。

于 2012-09-17T23:02:35.970 に答える
1

ストリームをラップできるのは1回だけです。何度もラップすると、便利というよりも混乱する可能性が高くなります。

ストリームが閉じられると再開されないため、文字を読み取ってストリームが終了したかどうかを確認し、ストリームを破棄することはあまり役に立ちません。とにかく操作がブロックされるときにスリープすることもあまり役に立ちません。

Integerコードを使用する代わりに、列挙値を使用します。これはよりクリーンになり、switchステートメントを使用できるようになります。

于 2012-09-17T11:45:34.190 に答える