Java 我应该在何时何地使用close()方法来避免ObjectInputStream中的IOException?
我正在尝试通过tcp从客户端程序读取对象。正如您在这一行中看到的,我创建了objectInput:Java 我应该在何时何地使用close()方法来避免ObjectInputStream中的IOException?,java,sockets,networking,tcp,objectinputstream,Java,Sockets,Networking,Tcp,Objectinputstream,我正在尝试通过tcp从客户端程序读取对象。正如您在这一行中看到的,我创建了objectInput: ObjectInputStream objectInput = new ObjectInputStream(incoming.getInputStream()); 然后从另一个程序读取我的输入。在我做了一些小改动来清理程序之前,它一直工作得很好。我个人认为我补充说 objectInput.clsoe(); 我的问题是,在阅读对象之后,我应该关闭objectInputStream还是保持不关闭?
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();
}
}
你应该在完成阅读或写作后关闭流。 在本例中,当您完全读取了文件并且不再需要从流中读取文件时,应该关闭InputStream 简而言之,您应该在流的工作结束时关闭它。 它可能在程序的末尾或if循环之后…取决于您的用例
希望这会有所帮助。您的代码片段相当长,因此我将尝试给您一个一般性的答案,希望它能帮助您 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();
}
}
或者简单地将该方法声明为抛出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块头中的所有实现接口可关闭的资源都将自动关闭。这一行堆栈跟踪表明,在初始化ObjectInputStream时,而不是在关闭时发生异常
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
最可能的原因是远程客户端没有打开ObjectOutputStream。它可能已经写入了其他类型的数据,或者它可能已经关闭了其输出流或者只是退出了。我是这样做的,不同的示例:
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方法的通用抛出异常来传递。如果在Java 7上,请使用自动资源管理。如果没有,请使用finally块关闭。谢谢您的回复。在我看来,这个错误并不是因为亲密。因为当它到达ObjectInputStream objectInput=new ObjectInputStreamincoming.getInputStream时;它获取错误。关闭。我认为他正在为每条消息打开一个新的ObjectInputStream,并且没有找到正确的流头,等等,因为对等方没有打开一个新的对应ObjectOutputStream。在连接游戏的生命周期中使用相同的流是旧的。问题是我向服务器发送了一条消息add,然后向服务器中的数据库发送了要添加的对象。在对象端,我首先读了add消息,这很酷,但是我读了还没有发送的对象,为了避免这个问题,我添加了Thread.sleep1000;发送消息后添加到客户端。无论如何,感谢您的支持reply@Bernard将睡眠添加到网络代码中只是一个简单的编程。可能需要刷新输出流。