java.io.EOFException在Java Eclipse中发生

huangapple go评论82阅读模式
英文:

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(&quot;localhost&quot;, 9999);
			
			while(true) {
				ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
				byte[] buf = new byte[1024];
				FileOutputStream fout = new FileOutputStream(&quot;c:/hyebin/hyebin/excercise.jpg&quot;);
				
				while((ois.read(buf, 0, buf.length))!=-1){
					fout.write(buf, 0, buf.length);
				}
				System.out.println(&quot;파일 수신 및 저장 성공&quot;);
				
			}
		} 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.&lt;init&gt;(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

这段代码存在各种问题。

  1. while(true) 部分非常奇怪,会导致你看到的异常。
  2. 使用了 ObjectInputStream,但完全没有理由这么做。普通的输入流已经有 read() 函数了。不要将你的套接字包装在 ObjectInputStream 中。
  3. ois.read 并没有读取整个缓冲区。它至少会读取 1 个字节,可能会读取更多,甚至可能是整个缓冲区,但这不是必然的。你忽略了它实际读取了多少字节,然后将整个缓冲区写入文件,这意味着如果网络数据包的大小小于文件大小,你的代码就会出错。你需要保存 read 调用返回的值,如果是 -1,则停止,如果不是,则写入相应数量的字节(将该值作为写方法的第三个参数,代替 buf.length)。
  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("파일 수신 및 저장 성공");
}

简单吧,是吧?通常最好查阅你正在使用的东西的 Java 文档,以弄清如何使用它,并找到任何有用的快捷方式,比如 transferTo 方法。

英文:

This code is all sorts of problematic.

  1. The while(true) is just bizarre, and causes the exception you see.
  2. ObjectInputStream is used, but for absolutely no reason. plain jane inputstreams have the read() function. Don't wrap your socket in the ObjectInputStream.
  3. 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 the read call, if it is -1, stop, if it is not, write that many bytes (provide that value instead of buf.length as third arg to the write method
  4. Your exception handling is deplorable. On failure, this code prints and continues.
  5. The error is in line 14 - see the client.java:14 bit in your stack trace? That's useful information.
  6. 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.
  7. 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 = &quot;c:/hyebin/hyebin.exercise.jpg&quot;;
public static void main(String[] args) throws Exception {
    Socket socket = new Socket(&quot;localhost&quot;, 9999);
    try (
        InputStream in = socket.getInputStream();
        FileOutputStream out = new FileOutputStream(OUT_FILE)) {

        in.transferTo(out);
    }
    System.out.println(&quot;파일 수신 및 저장 성공&quot;);
}

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.

huangapple
  • 本文由 发表于 2020年5月30日 20:00:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/62102121.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定