在 Java 中使用 DataInputStream 读取一个整数

Read an integer with DataInputStream in Java

我有这个 Java 代码:

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class DemoApp {

    public static void main(String args[]) {

        try (DataInputStream dis = new DataInputStream(new FileInputStream("abc.txt"))) {

            int k = dis.readInt();
            System.out.println(k);
        }

        catch (FileNotFoundException fnfe) {

            System.out.printf("ERROR: %s", fnfe); 
        }

        catch (IOException ioe) {

            System.out.printf("ERROR: %s", ioe);
        }
    }

}

当 abc.txt 文件包含数字 987 我有这个错误: java.io.EOFException 如果 abc.txt 包含数字 1234 当我 运行 程序时 我有这个结果:825373492。我只是想了解 DataInputStream 中的 readInt() 方法究竟是如何工作的,以及为什么某些数字出现此错误。谢谢!

abc.txt包含字符1234,其ASCII表示为十六进制数0x31、0x32、0x33和0x34。如果你把它们写出来,你会注意到十六进制数 0x31323334 的十进制值为 825373492.

解决方法是一次读取一个字节(不是一次读取一个Integer),然后从字节中减去0x30,得到它所代表的数字。对于每个数字,对于从文件中读取的每个字节,您必须将先前的结果左移十倍(将十移动到百,等等)然后将当前数字添加到它。

或者,将字符作为字符串读取,并将其传递给 Integer.parseInt 方法,该方法将为您进行繁琐的 character-to-digit 转换。要将字符作为字符串读取,您可能需要使用 BufferedReader d = new BufferedReader(new InputStreamReader(in)).

或者扫描仪,正如 davidxxx 所建议的那样。

DataInputStream 旨在从二进制流(字节)中读取字节,并且您的文本文件包含整数值的文本表示。
所以它不能工作。

您可以在 DataInputStream.readInt() javadoc 中找到信息:

See the general contract of the readInt method of DataInput.

其中 DataInput().readInt() 表示

The DataInput interface provides for reading bytes from a binary stream and reconstructing from them data in any of the Java primitive types. ...

The value returned is:

(((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff))

987 被读取为 57, 56, 55 字节。它缺少一个字节成为 int,因为 int 以 4 个字节表示。
而在 readInt() 调用期间抛出的 EOFException 作为 此输入流在读取四个字节之前到达末尾。
通过在文本文件中添加一个额外的数字,您可以读取 4 个字节。所以它 "works" :可以读取 4 个字节,但 1234 被读取为 49、50、51、52 ​​个字节,根据 DataInput.readInt() 规范生成 825373492 int。

要从文本文件中读取 int 值,您可以使用 Scanner 例如:

try (Scanner sc = new Scanner(new File("abc.txt"))) {
        int i = sc.nextInt();
        System.out.println(i);
}