0

tcpを介してクライアントプログラムからオブジェクトを読み取ろうとしています。この行でわかるように、objectInputを作成しました。

ObjectInputStream objectInput = new ObjectInputStream(incoming.getInputStream());

そして、他のプログラムから私の入力を読みます。プログラムをクリーンアップするために小さな変更を加えるまでは、以前は正常に機能していました。個人的に私が追加したと仮定します

objectInput.clsoe();

私の質問は、オブジェクトを読んだ後、objectInputStreamを閉じるか、閉じずにそのままにしておく必要がありますか?使用後すぐに閉じるか、ifブロックの最後またはプログラムの最後に閉じる必要がありますか?クローズの効果は何ですか?ちなみに私は詳細なドキュメントを読みました。

エラーは次のとおりです。

java.io.EOFException
    at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2280)
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2749)
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:779)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
    at Server.ClientWorker.run(MyCollectionServer.java:116)
    at java.lang.Thread.run(Thread.java:680)

これが私のコードです:

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        try 
        {
            serverSocket = new ServerSocket(port);  
        } 
        catch (IOException e) 
                {
            e.printStackTrace();
        }
        while(true)
        {   
            ClientWorker w;
            try
            {   
                w = new ClientWorker(serverSocket.accept());
                Thread t = new Thread(w);
                t.start();
            }
            catch(IOException e)
            {
                e.printStackTrace();
                break;
            }   
        }
    }
}

class ClientWorker implements Runnable
{
.....
    private Socket incoming;
    public ClientWorker(Socket incoming)
    {
        myList = new ArrayList<PureAlbum>();
        loadList();
        this.incoming = incoming;
    }

.....
    public synchronized  void run()
    {

else if(request.compareTo("AddAlbum")==0)
        {
            try
            {
                ObjectInputStream objectInput = new ObjectInputStream(incoming.getInputStream()); //This is the line mentioned in the error
                PureAlbum object = (PureAlbum) objectInput.readObject();


                if(object instanceof CDAlbum)
                {
                    CDAlbum a = (CDAlbum) object;
                    myList.add(a);
                    System.out.println("Artist = " + a.getArtist());
                }
                else if(object instanceof Client.au.edu.uow.Collection.DVDAlbum)
                {
                    myList.add((DVDAlbum) object);              
                }
                else
                {
                    System.err.println("Warning : The object to add to database is unknown! "+ object.getClass() + "*");
                    System.exit(0);
                }


            }
            catch (UnknownHostException e) 
            {
                System.err.println("Can not read the host name");
                e.printStackTrace();
            } 
            catch (IOException e) 
            {
                System.err.println("Can not read the FILE name"); //This exception has been called
                e.printStackTrace(); 
            }
            catch (ClassNotFoundException e) 
            {
                e.printStackTrace();
            }
        }
4

4 に答える 4

5

あなたのコード フラグメントはかなり長いので、一般的な回答をしようと思います。

Java 7 より前の の典型的な使用パターンは次のstream.close()とおりです。

InputStream in = null; 
try {
    InputStream in = .....; // create your input stream;
    // use input stream
} catch (IOException e) {
    // do what you need here
} finally {
    if (in != null) {
        in.close();
    }
}

または単にメソッドを次のように宣言してから、次のthrows IOExceptionように記述します。

InputStream in = null; 
try {
    InputStream in = .....; // create your input stream;
    // use input stream
} finally {
    if (in != null) {
        in.close();
    }
}

この例にはcatchセクションが含まれていないことに注意してください。

Java 7 以降、言語の新しい機能を利用できます。

try (
    InputStream in = .....; // create your input stream;
) {
    // use input stream
}

電話をかける必要さえありませんclose()。インターフェイスを実装する try ブロックのヘッダーに定義されているすべてのリソースは、Closable自動的に閉じられます。

于 2012-10-16T12:21:27.567 に答える
3

ObjectInputStreamスタック トレースのこの行は、 を閉じるときではなく、 を初期化するときに例外が発生していることを示しています。

at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)

最も可能性の高い原因は、リモート クライアントがObjectOutputStream. 他の種類のデータを書き込んだか、出力ストリームを閉じたか、単に終了した可能性があります。

于 2012-10-16T13:47:28.413 に答える
1

読み取りまたは書き込みが完了したら、ストリームを閉じる必要があります。この場合、ファイルを完全に読み取り、ストリームからファイルを読み取る必要がなくなったら、InputStream を閉じる必要があります。

要するに、作業が終わったらストリームを閉じる必要があります。プログラムの最後またはifループの後にある可能性があります....ユースケースによって異なります。

これが役立つことを願っています。

于 2012-10-16T12:19:17.147 に答える