java - DataInputStream vs InputStreamReader,试图从概念上理解两者

标签 java datainputstream inputstreamreader

暂时我的理解是:

DataInputStream是一个 InputStream子类,因此它读取和写入字节。如果您正在读取字节并且您知道它们都将是 int s 或其他一些原始数据类型,那么你可以读取这些 byte使用 DataInputStream 直接进入原语.

  • 问题:在读取内容之前,您是否需要知道正在读取的内容的类型(整数、字符串等)?整个文件是否需要包含一种原始类型?

我的问题是:为什么不使用 InputStreamReader环绕 InputStream的字节数据?使用这种方法,您仍然在读取字节,然后将它们转换为表示字符的整数。哪些整数表示哪些字符取决于指定的字符集,例如“UTF-8”。

  • 问题:在什么情况下会出现 InputStreamReader无法在 DataInputStream 的地方工作会有用吗?

我猜的答案:如果速度真的很重要,而且你能做到,那么转换 InputStream的字节数据通过 DataInputStream 直接传递给原语会是要走的路吗?这避免了 Reader必须将字节数据“转换”为 int第一的;并且它不会依赖于提供字符集来解释返回的整数表示哪个字符。我想这就是人们所说的 DataInputStream 的意思允许独立于机器读取底层数据。

  • 简化:DataInputStream可以将字节直接转换为原语。

引发整个问题的问题:我正在阅读以下教程代码:

    FileInputStream fis = openFileInput("myFileText");

    BufferedReader reader = new BufferedReader( new InputStreamReader( new DataInputStream(fis)));

    EditText editText = (EditText)findViewById(R.id.edit_text);

    String line;

    while(  (line = reader.readline()) != null){

        editText.append(line);
        editText.append("\n");
    }

...我不明白为什么导师选择使用new DataInputStream(fis)因为看起来没有任何直接从字节转换为基元的能力被利用?

  • 我错过了什么吗?

感谢您的见解。

最佳答案

InputStreamReader 和DataInputStream 是完全不同的。

DataInputStream is an InputStream subclass, hence it reads and writes bytes.

这是不正确的,InputStream 仅读取字节,而 DataInputStream 对其进行扩展,因此您也可以读取 Java 原语。他们都不能写入任何数据。

Question: would you would need to know the type (int, string, etc) of the content being read before it is read? And would the whole file need to consist of that one primitive type?

DataInputStream 只能用于读取之前由 DataOutputStream 写入的数据。如果不是这种情况,您的 DataInputStream 不太可能“理解”您正在阅读的数据并将返回随机数据。 因此,您应该清楚地知道相应的DataOutputStream以何种顺序写入了何种类型的数据。

例如,如果您想保存应用程序的状态(假设它由几个数字组成):

public void exit() {
    //...
    DataOutputStream dout = new DataOutputStream(new FileOutputStream(STATE_FILE));
    dout.write(somefloat);
    dout.write(someInt);
    dout.write(someDouble);
}

public void startup() {
    DataInputStream dout = new DataInputStream(new FileInputStream(STATE_FILE));
    //exactly the same order, otherwise it's going to return weird data
    dout.read(somefloat);
    dout.read(someInt);
    dout.read(someDouble);
}

这基本上就是 DataInputStream 和 DataOutputStream 的全部内容:将原始变量写入流并读取它们。

现在,InputStreamReader 完全不同了。 InputStreamReader 将编码文本“翻译”为 Java 字符。 您基本上可以使用任何文本流(知道其编码)并使用 InputStreamReader 从该源读取 Java 字符。

With this approach you are still reading the bytes, then converting them to integers that represent characters. Which integers represent which characters depends on the character set specified, e.g., "UTF-8".

字符编码不仅仅是代码点和字符之间的简单映射。 除此之外,它指定代码点在内存中的表示方式。 例如,UTF-8 和 UTF-16 共享相同的字符映射,但是如果您尝试将 UTF-8 流读取为 UTF-16,则 InputStreamReader 会显着失败。 由四个字节 un UTF-8 ('a', 'a', 'b', 'b') 表示的字符串 aabb 将被转换为两个字符。两个 a 和 b 的值将被视为一个字符。我懒得去查那些会是哪些字符,但它们会很奇怪。

InputStreamReader 处理所有这些内容,因此如果您知道编码,则能够从任何来源(与 DataInputStream 不同)读取文本。

Question: In what case would an InputStreamReader fail to work where a DataInputStream would work?

现在应该很清楚了。由于这两个类的目的完全不同,因此您不应该问这个问题。 InputStreamReader 不会像 DataInputStream 那样将字节转换为整数,并且不是为此目的而设计的。

在教程代码中,我很确定您可以省略 DataInputStream:

BufferedReader reader = new BufferedReader( new InputStreamReader(fis));

但是,DataInputStream 提供了与 InputStream 相同的方法,这就是为什么将 FileInputStream 包装在其中并没有错(尽管这是不必要的)。

关于java - DataInputStream vs InputStreamReader,试图从概念上理解两者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25511536/

相关文章:

java - 允许更改 key 的最大堆

java - 在Java中使用ObjectInputStream/ObjectOutputStream实现网络 "packets"的优点和缺点?

java - PrintStream 无缘无故出错?

java - 如何从InputStreamReader读取整数

java - 如何将txt文件读取到android项目文件夹中

java - 从文件中读取字节

java - 我需要使用 TableLayout...我已经下载了 .jar...不知道如何使用它

java - 如何从 Android 中的 firebase 返回值?

java - 如何将 Mono 中的嵌套列表转换为 Flux?

java - 如何从 Java 中的字节数组中删除前 4 个字节?