简体   繁体   English

用Java中的DataInputStream读取一个整数

[英]Read an integer with DataInputStream in Java

I have this Java code: 我有这个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);
        }
    }

}

When the abc.txt file contains the number 987 I have this ERROR: java.io.EOFException if the abc.txt contains the number 1234 when I run the program I have this result: 825373492. I just want to understand how exactly is working this readInt() method from DataInputStream and why I have this error for some numbers. 当abc.txt文件包含数字987时,我出现此错误:java.io.EOFException如果运行程序时abc.txt包含数字1234,我将得到以下结果:825373492。我只想了解其工作原理DataInputStream的readInt()方法以及为什么我在某些数字上遇到此错误。 Thank you! 谢谢!

DataInputStream is designed to read bytes from a binary stream (bytes) and your text file contains a textual representation of a integer value. DataInputStream旨在从二进制流(字节)中读取字节,并且您的文本文件包含整数值的文本表示形式。
So it cannot work. 所以它行不通。

You can find the information in the DataInputStream.readInt() javadoc : 您可以在DataInputStream.readInt() javadoc中找到该信息:

See the general contract of the readInt method of DataInput. 请参见DataInput的readInt方法的常规协定。

Where DataInput().readInt() states 其中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. DataInput接口提供了从二进制流中读取字节并从中重建任何Java原语类型的数据的功能。 ... ...

The value returned is: 返回的值是:

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

987 is read as 57, 56, 55 bytes. 987读取为57, 56, 55字节。 It misses a byte to be an int as int are represented on 4 bytes. 它缺少一个字节作为int因为int在4个字节上表示。
Whereas The EOFException thrown during readInt() invocation as this input stream reached the end before reading four bytes. readInt()调用期间,此输入流在读取四个字节之前到达末尾时引发了EOFException
By adding an additional digit in your text file, you have 4 bytes to read. 通过在文本文件中添加其他数字,您可以读取4个字节。 So it "works" : the 4 bytes can be read but 1234 is read as 49, 50, 51, 52 bytes that produces the 825373492 int according to the DataInput.readInt() specification. 因此它“有效”:可以读取4个字节,但是将1234读取为49、50、51、52个字节,这将根据DataInput.readInt()规范生成825373492 int。

To read int value from a text file you can use a Scanner such as : 要从文本文件中读取int值,可以使用以下Scanner

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

abc.txt contains the characters 1234, whose ASCII representations are the hexadecimal numbers 0x31, 0x32, 0x33 and 0x34. abc.txt包含字符1234,其ASCII表示形式为十六进制数字0x31、0x32、0x33和0x34。 If you write those out you will notice that the hexadecimal number 0x31323334 has the decimal value 825373492. 如果将它们写出来,您会注意到十六进制数字0x31323334的十进制值为825373492。

The solution is to read a byte at a time (not an Integer at a time), and subtract 0x30 from the byte to find the digit it represents. 解决方案是一次读取一个字节(一次不读取整数),然后从该字节中减去0x30来找到它代表的数字。 For each digit, you have to shift the previous result left by a factor of ten (to move tens to hundreds, and so on) and then add the current digit to it, for each byte you read from the file. 对于每个数字,对于从文件中读取的每个字节,您都必须将前一个结果左移十倍(以移动几十到几百,依此类推),然后向其添加当前数字。

Alternatively, read the characters as a String, and pass it to the Integer.parseInt method, which will do the fiddly character-to-digit conversion for you. 或者,将字符读取为String,然后将其传递给Integer.parseInt方法,该方法将为您完成字符到数字的转换。 To read the characters as a String, you may want to use BufferedReader d = new BufferedReader(new InputStreamReader(in)) . 要以字符串形式读取字符,您可能需要使用BufferedReader d = new BufferedReader(new InputStreamReader(in))

Or a Scanner, as davidxxx suggests. 或扫描程序,如davidxxx建议的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM