当前位置: 首页 > 知识库问答 >
问题:

理解java中的二进制、字节流和字符

戚澄邈
2023-03-14

我在理解JavaIO类中的一些概念时有些困难。例如,有两种类型的流,字节流和字符流。据我所知,字节流逐个字节读取。

1.如果java中的char存储为16位(2字节)的数据类型,那么我怎么可能使用面向字节的输入流从文件中准确读取char,比如'A',例如FileInputStream?

2。是因为我使用的字符(在ascii图表上大多在0到122之间)存储在分配的两个字节中的一个字节中吗?

3. DataInputStream/DataOutputStream允许我读写二进制数据,其他输入流如FileInputStream/FileOutputStream允许我读写什么?我基本上想知道当我希望输出数据作为我可以阅读的文本(使用像记事本这样的简单文本编辑器)时使用哪个流,而不是当我希望将其编码为原始二进制数据(在记事本中看起来像垃圾的文本)?

很难理解java中流的概念,以及何时使用。

共有3个答案

丁阳炎
2023-03-14

在我回答你的问题之前,有几件非常基本的事情需要理解。

  1. 在最低层InputStream/OutputStream),一切都是位和字节。所以最低层的流处理原始数据,即位/字节。
  2. 现在要将原始字节转换为可读字符,您需要字符编码或字符集。因此,简而言之,字符编码是一条指令(从字节到可视字符的映射),用于将原始字节从定义的集合转换为可读字符(例如UTF-8)。

现在来回答你的问题:

如果java中的char存储为16位(2字节)数据类型,那么我如何能够使用面向字节的输入流(例如FileInputStream)从文件中准确读取char(例如A)?

例如,为了读取字符数据,原始输入流被包装在面向字符的流中

FileInputStream fis = new FileInputStream("test.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF8"); 

正如javadoc所说,InputStreamReader是从字节流到字符流的桥梁。

我使用的字符(在ascii图表上主要在0到122之间)是否存储在分配的两个字节中的一个字节中?

是的。ascii字符集是较大的Unicode集的子集,如UTF-8

数据输入流/数据输出流允许我读写二进制数据,其他输入流如文件输入流/文件输出流允许我读写到底是什么?

我猜现在很明显,DataInputStream/DataOutputStream用于字符数据,而ileInputStream/FileOutputStream用于原始数据。

我基本上想知道,当我希望将数据输出为可以读取的文本(使用记事本之类的简单文本编辑器)时,与当我希望将其编码为原始二进制数据(记事本中看起来像垃圾的文本)时,应该使用哪个流?

对于文本,请使用任何读者/作者(以下是一个示例)

司徒茂实
2023-03-14

如果java中的char存储为16位(2字节)数据类型,那么我如何能够使用面向字节的输入流(例如FileInputStream)从文件中准确读取char(例如A)?

试着做

System.out.println(Integer.toBinaryString('A'));

它打印出字符'A'的二进制表示形式。这张照片

1000001

因为'A'是一个char,它实际上是用16位存储的

00000000 01000001

所以你所要做的就是读取两个连续的字节,并适当地使用它们来形成一个char

ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0b00000000, 0b01000001});
System.out.println(buffer.getChar());

哪张照片

A

它所做的是将数组中的第一个byte用作char中的前8位,并将第二个byte用作最后8位。

DataInputStream/DataOutputStream允许我读写二进制数据,而FileInputStream/FileOutputStream等其他输入流允许我读写什么?我基本上想知道,当我希望将数据输出为可以读取的文本(使用记事本之类的简单文本编辑器)时,与当我希望将其编码为原始二进制数据(记事本中看起来像垃圾的文本)时,应该使用哪个流?

无论你是在写文本还是其他任何东西,都是位和字节。你可以做得很好

"someString".getBytes()

然后写下来。所以这并不重要。使用最能代表你正在做的事情。通常,您可以用PrintWriter包装底层OutputStream,用ScannerBufferedReader包装底层InputStream

阚吕恭
2023-03-14

取决于您正在读取的文件的格式。

如果文件是ASCII字节流,则执行以下操作:

InputStream is = new FileInputStream( filePath );
Reader reader = new InputStreamReader( is, "ISO-8859-1" );

char ch = reader.read();

您总是首先在面向字节的文件上打开输入流。然后,InputStreamReader将字节转换为字符。当然,在本例中,ISO-8859-1是从单字节值到完全相同的字符值的映射。显然,其他映射是可能的,但ISO-8859-1恰好与Unicode集合的前255个字符相同,而其中的前127个字符恰好与ASCII相同。

写作时使用:

OutputStream os = new FileOutputStream( filePath ) ;
Writer w = new OutputStreamWriter( os, "ISO-8859-1" );

w.write( ch );

同样,是根据ISO-8859-1字符集在字符和字节流之间进行适当转换的输出流写入器。结果文件每个字符将有一个字节。

下面是几个正确的基本流模式的例子。

如果使用上述方法,则执行以下操作:

w.write("AAAA");
w.flush();
w.close();

结果文件将包含4个字节,每个字节的值为65。使用顶部的代码读回该文件将在内存中产生四个“A”字符,但在内存中,每个字符占用16位。

如果文件是在不同的字符集中编码的,可能包括多个字节字符,那么只需在输入流读取器/输出流写入器中使用正确的编码,读写时就会进行正确的转换。

UTF-8不是一个字符集,而是将常规unicode字符编码为字节序列,事实证明,UTF-8编码非常聪明,因为unicode字符的前127个字符映射为前127个字节值(作为单个字节)。然后是人物

了解这一点非常重要。我建议您不要尝试以任何其他方式将字节转换为字符。当然,这是可能的,但这是一种浪费,因为流中的转换非常可靠和正确。

(更糟糕的是……实际上,一个字符是32位的量,其中20位可以用一种称为UTF-16的编码编码成16位字符值的序列。建议您暂时忽略这一点,但请注意,即使在由16位字符值组成的Java字符串中,也有一些双字符序列。)

 类似资料:
  • 我在Java中有以下问题。我使用的加密算法可以产生负字节作为结果,出于我的目的,我必须能够用二进制处理它们。对于负字节,8中的第一个或最高有效位为1。当我稍后尝试将二进制字符串转换回字节时,我得到了一个,因为我的字节太长了。我可以告诉Java将其视为无符号字节,并以负字节结束吗?到目前为止,我的代码是: 在Java中,有没有更好的方法从二进制文件解析有符号字节?提前谢谢!

  • 本文向大家介绍详解JAVA 字节流和字符流,包括了详解JAVA 字节流和字符流的使用技巧和注意事项,需要的朋友参考一下 1、InputStream 和 Reader InputStream 和 Reader 是所有输入流的抽象基类,本身并不能创建实例来执行输入,但它们将成为所有输入流的模板,所以它们的方法是所有输入流都可使用的方法。 在 InputStream 里包含如下三个方法。 int rea

  • 本文向大家介绍java 字节流和字符流的区别详解,包括了java 字节流和字符流的区别详解的使用技巧和注意事项,需要的朋友参考一下 字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢? 实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件,如图所示。 下面以两个写文件的操作为主进行比较,但是在操作时

  • 本文向大家介绍详解Java中字符流与字节流的区别,包括了详解Java中字符流与字节流的区别的使用技巧和注意事项,需要的朋友参考一下 本文为大家分析了Java中字符流与字节流的区别,供大家参考,具体内容如下 1. 什么是流     Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列。和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中

  • 问题内容: 请解释什么是字节流和字符流。这些到底是什么意思?Microsoft Word文档是面向字节还是面向字符? 谢谢 问题答案: 流是顺序访问文件的一种方式。字节流逐字节访问文件。字节流适用于任何类型的文件,但不适用于文本文件。例如,如果文件使用unicode编码,并且一个字符用两个字节表示,则字节流将分别处理这些字节,您需要自己进行转换。 字符流将逐字符读取文件。必须为字符流提供文件的编码

  • 本文向大家介绍Python中struct模块对字节流/二进制流的操作教程,包括了Python中struct模块对字节流/二进制流的操作教程的使用技巧和注意事项,需要的朋友参考一下 前言 最近使用Python解析IDX文件格式的MNIST数据集,需要对二进制文件进行读取操作,其中我使用的是struct模块。查了网上挺多教程都写的挺好的,不过对新手不是很友好,所以我重新整理了一些笔记以供快速上手。 注