【问题标题】:Are StreamWriter and BinaryWriter interchangeable when it comes to write stringsStreamWriter 和 BinaryWriter 在写入字符串时是否可以互换
【发布时间】:2021-07-22 00:18:55
【问题描述】:

StreamWriterBinaryWriter 的 MSDN 页面中,您可以清楚地看到差异:

StreamWriter:

实现一个 TextWriter 用于写作 字符到特定的流中 编码。

还有:

BinaryWriter:

以二进制形式将原始类型写入 a 流并支持写入字符串 特定的编码。

我知道 BinaryWriter 最重要的特性是它可以将原始类型写入二进制,这可以更紧凑和高效(考虑写入整数 23861398 - 二进制写入器需要 4 个字节,但流写入器需要8、16 甚至 32,具体取决于编码)。

但是说到写字符串,我们可以说StreamWriter和BinaryWriter是可以互换的吗?

【问题讨论】:

标签: c# .net


【解决方案1】:

来自the BinaryWriter documentation

以 BinaryWriter 的当前编码向该流写入一个以长度为前缀的字符串,并根据使用的编码和写入流的特定字符将流的当前位置前进。

和:

Length-prefixed 表示此方法首先将使用 BinaryWriter 实例的当前编码编码的字符串的长度(以字节为单位)写入流。该值写为无符号整数。然后,此方法将那么多字节写入流中。

例如,字符串“A”的长度为 1,但使用 UTF-16 编码时;长度是2个字节,所以写在prefix里面的值是2,写到stream里面有3个byte,包括prefix。

StreamWriter 类不会将任何字符串长度写入输出。它只是自己编写文本

两者都尊重您在创建对象时指定的编码。正在编写的实际文本使用该编码。

所以根据你所说的“可互换”,它们要么是,要么不是。 我会说它们不是,但如果您所看到的只是代表自己编写的文本的字节序列,那么您可能会认为它们是。

解决您的评论:

我是 BinaryWriter 的新手,为什么需要先将长度写入流?为什么不直接写“真实数据”呢?

与只写入一种数据的StreamWriter 不同,BinaryWriter 可以将各种数据(包括原始字节和各种原始类型)写入单个Stream。在编写每一个时,它需要一种方法来指示该特定数据部分的结束位置。这样BinaryWriter 的阅读对应对象BinaryReader 就有办法知道每个数据部分的结束位置。

对于某些事情来说,这很简单,因为数据项本身是固定大小的。 System.Int32 是 4 个字节,System.Int64 是 8 个字节,以此类推。它们是固定长度的,因此在读取时您只需读取预期的字节数。

但是string 对象是可变长度的。有两种常见的方法来处理这个问题:在字符串前面加上一个计数,或者在字符串结尾加上一个空字符 ('\0')。内存中的 .NET 字符串被计算在内,而不是以 null 结尾,因此字符串对象实际上可以包含一个 null 字符,因此以 null 结尾的字符串不适用于将字符串存储在文件中.

因此使用带有字节数的前缀。

【讨论】:

  • 再次感谢。所以你的意思是我可以使用 BinaryWriter 写一点,然后将字符串写入同一个流?如果没问题,那么当您使用 BinaryReader 读取时,是的,您确实有第一部分数据的大小,但是您不跟踪数据类型,那么您怎么知道它是 int,而不是两个字符字符串?
  • “但你不跟踪数据类型”——问题就在这里。要成功使用BinaryWriterBinaryReader,您必须已经知道数据类型的确切顺序。你不需要知道,例如预先确定字符串的长度,因为长度包含在写入的数据中。但是您仍然需要了解有关数据的一些信息。否则对你有什么好处?而且,您不仅需要知道数据是什么,还需要知道它的含义。使用BinaryWriter 不会使这些要求神奇地消失。它只是提供了一种格式化特定数据的机制。
【解决方案2】:

不,它们绝对不能互换。 BinaryWriter 是一个自以为是的基本 IO 工具,用于写入二进制输出; StreamWriter 用于编写文本输出。任何时候输出看起来相似纯属偶然 - 它们应该绝对不能可互换使用。

对于字符串,它们将看起来相似,但这仅仅是因为两者最终都只是使用文本编码。 他们的样板是非常不同的(BinaryWriter 使用长度前缀等)。

如果您希望像使用另一个一样使用一个:您可能做错了什么。如果您明确尝试做什么,我们或许可以提供指导。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 2012-01-25
    • 2018-05-12
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    相关资源
    最近更新 更多