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

您的代码片段很长,因此我将尝试给您一个一般性的答案,希望对您有所帮助。

stream.close()java 7之前的典型使用模式是:

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

完成阅读或写作后,您应该关闭 Stream。在这种情况下,您应该在完全读取文件并且不再需要从流中读取文件后关闭 InputStream。

简而言之,您应该在 Stream 工作结束时关闭它。它可能在程序结束或 if 循环之后......取决于您的用例。

希望这会有所帮助。

于 2012-10-16T12:19:17.147 回答
0

我这样做(不同的例子):

private void readFile() throws Exception {
    FileInputStream fis = null;
    ObjectInputStream ois = null;
    Object aux = null;

    try {

        fis = new FileInputStream("lib.dat");
        ois = new ObjectInputStream(fis);

        do {
            aux = ois.readObject();
            if (aux instanceof MyObject)
                this.myObjectInstance.add((MyObject) aux);
        } while (true);

    } catch (EOFException e) {
        ois.close();
    }
}

这样,我将在楼上发送任何相关的“错误”异常以进行处理,一旦 EndOfFileException 启动,就会专门捕获该异常以正确关闭流。

该对象必须在 Try 块之外定义,才能从 Catch 块访问。

close() 方法也可以抛出一个 IOException,这不能被我们的 Try 块捕获,这必须由 readFile() 方法的通用“抛出异常”传递。

于 2013-11-22T23:59:27.550 回答