英文:
java.io.EOFException in java eclipse
问题
try {
socket = new Socket("localhost", 9999);
while (true) {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
byte[] buf = new byte[1024];
FileOutputStream fout = new FileOutputStream("c:/hyebin/hyebin/excercise.jpg");
while ((ois.read(buf, 0, buf.length)) != -1) {
fout.write(buf, 0, buf.length);
}
System.out.println("文件接收并保存成功");
}
} catch (Exception ex) {
ex.printStackTrace();
}
java.io.EOFException
at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2890)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3385)
at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:942)
at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:385)
at comm/comm.client.main(client.java:14)
这是我的客户端代码。第一次代码正常运行。但是从第二次保存开始就会出现上述错误。我不知道错误出现在哪里。
英文:
try {
socket = new Socket("localhost", 9999);
while(true) {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
byte[] buf = new byte[1024];
FileOutputStream fout = new FileOutputStream("c:/hyebin/hyebin/excercise.jpg");
while((ois.read(buf, 0, buf.length))!=-1){
fout.write(buf, 0, buf.length);
}
System.out.println("파일 수신 및 저장 성공");
}
} catch (Exception ex) {
ex.printStackTrace();
}
java.io.EOFException
at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2890)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3385)
at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:942)
at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:385)
at comm/comm.client.main(client.java:14)
This is my client code. The first code runs normally. However, such an error occurs from the second time it is saved. I don't know where the error occurs.
答案1
得分: 2
这段代码存在各种问题。
while(true)
部分非常奇怪,会导致你看到的异常。- 使用了
ObjectInputStream
,但完全没有理由这么做。普通的输入流已经有read()
函数了。不要将你的套接字包装在ObjectInputStream
中。 ois.read
并没有读取整个缓冲区。它至少会读取 1 个字节,可能会读取更多,甚至可能是整个缓冲区,但这不是必然的。你忽略了它实际读取了多少字节,然后将整个缓冲区写入文件,这意味着如果网络数据包的大小小于文件大小,你的代码就会出错。你需要保存read
调用返回的值,如果是 -1,则停止,如果不是,则写入相应数量的字节(将该值作为写方法的第三个参数,代替buf.length
)。- 你的异常处理令人难以接受。在失败时,该代码会打印消息并继续执行。
- 错误在第 14 行 - 在堆栈跟踪中看到了
client.java:14
部分吗?那是有用的信息。 - 必须保护资源:你必须关闭资源,而且必须这样做,即使你的代码通过异常或其他方式退出。有一个相应的结构可以做到这一点,叫做 ARM 结构(自动资源管理),也叫做 try-with。
- 当今的输入流已经有了一种方法,可以要求它们将自己直接转储到文件中。
将所有内容结合起来:
private static final String OUT_FILE = "c:/hyebin/hyebin.exercise.jpg";
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 9999);
try (
InputStream in = socket.getInputStream();
FileOutputStream out = new FileOutputStream(OUT_FILE)) {
in.transferTo(out);
}
System.out.println("파일 수신 및 저장 성공");
}
简单吧,是吧?通常最好查阅你正在使用的东西的 Java 文档,以弄清如何使用它,并找到任何有用的快捷方式,比如 transferTo
方法。
英文:
This code is all sorts of problematic.
- The while(true) is just bizarre, and causes the exception you see.
- ObjectInputStream is used, but for absolutely no reason. plain jane inputstreams have the read() function. Don't wrap your socket in the ObjectInputStream.
ois.read
does not read the full buffer. It reads at least 1 byte, and probably more, possibly the entire buffer, but it doesn't have to. You ignore how many bytes it did read, and then write the full buffer to the file, which means that if for example the network packet size is smaller than the file size, your code breaks. you need to save the value returned by theread
call, if it is -1, stop, if it is not, write that many bytes (provide that value instead ofbuf.length
as third arg to the write method- Your exception handling is deplorable. On failure, this code prints and continues.
- The error is in line 14 - see the
client.java:14
bit in your stack trace? That's useful information. - Resources must be guarded: You MUST close resources, and you must do so even if your code exits via exception or otherwise. There is a construct for this, called the ARM construct (automatic resource management), also called try-with.
- inputstreams have a method these days to ask them to just dump themselves into a file.
Combining it all:
private static final String OUT_FILE = "c:/hyebin/hyebin.exercise.jpg";
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 9999);
try (
InputStream in = socket.getInputStream();
FileOutputStream out = new FileOutputStream(OUT_FILE)) {
in.transferTo(out);
}
System.out.println("파일 수신 및 저장 성공");
}
easy, isn't it? It's generally a good idea to look at the javadoc of stuff you're using to figure out how to use it, and to find any useful shortcuts, such as the transferTo
method.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论