首页 > 解决方案 > java eclipse中的java.io.EOFException

问题描述

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)

这是我的客户代码。第一个代码运行正常。但是,从第二次保存时就会出现这样的错误。我不知道错误发生在哪里。

标签: javasocketstcp

解决方案


这段代码有各种各样的问题。

  1. while(true) 很奇怪,会导致您看到的异常。
  2. 使用了 ObjectInputStream,但绝对没有理由。普通简输入流具有 read() 功能。不要将您的套接字包装在 ObjectInputStream 中。
  3. ois.read不读取完整的缓冲区。它读取至少 1 个字节,可能更多,可能是整个缓冲区,但它不是必须的。您忽略它读取了多少字节,然后将完整的缓冲区写入文件,这意味着如果例如网络数据包大小小于文件大小,您的代码就会中断。您需要保存read调用返回的值,如果是 -1,则停止,如果不是,则写入那么多字节(提供该值而不是buf.length作为第三个 arg 到 write 方法
  4. 您的异常处理令人遗憾。失败时,此代码将打印并继续。
  5. 错误在第 14 行 - 看到client.java:14堆栈跟踪中的位了吗?这是有用的信息。
  6. 必须保护资源:您必须关闭资源,即使您的代码因异常或其他原因退出,您也必须这样做。为此有一个构造,称为 ARM 构造(自动资源管理),也称为 try-with。
  7. 这些天,输入流有一种方法可以要求他们将自己转储到文件中。

结合这一切:

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("파일 수신 및 저장 성공");
}

容易,不是吗?查看您正在使用的东西的 javadoc 以了解如何使用它并找到任何有用的快捷方式(例如transferTo方法)通常是一个好主意。


推荐阅读