c# – 在字符串中使用二进制数据时数据“丢失”了吗?

我尝试使用StreamReader类的ReadToEnd()方法读取JPG文件,该方法返回一个字符串。

但是出于某种原因,当我将此字符串写入文件时,它不会打开。

将数据读入字符串时会丢失什么?

字符串用于文本数据。 它们不是二进制数据 – 如果你以这种方式使用它们就会丢失数据(你可以使用的编码如果你很幸运就不会丢失数据,但是有一些微妙的问题仍然会让它成为一个非常糟糕的主意。)

如果您实际上正在处理文件,那么阅读整个文件的最简单方法是调用File.ReadAllBytes 。 如果必须处理任意流,请查看“从流中创建字节数组” 。

正如所有真正的程序员都知道的那样,唯一有用的数据结构是Array。 字符串,列表,结构,集合 – 这些都是数组的特殊情况,可以这样轻松地处理,而不会弄乱您的编程语言中的各种复杂情况。 花哨的数据类型最糟糕的是你必须声明它们,而且我们都知道,Real Programming Languages根据(六个字符)变量名的第一个字母进行隐式类型化。

此外,确定的Real Programmer可以用任何语言编写Fortran程序。


无论是谁修改了这个,都要么没有幽默感,要么没有民间传说知识。 以上内容摘自1983年由泰克的Ed Post撰写的一篇非常着名的致Datamation编辑的信。 这封信的标题是Real Programmers Do not Use Pascal

永远记住, 文本数据 二进制数据,二进制数据 不是 文本数据

String用于保存unicode字符; 不是二元的。 对于二进制,使用byte[]Stream 。 或Image等更专业的图像处理。

尽管名称如此,但StreamReader实际上是一个专门的TextReader – 即它是一个从Stream读取的TextReader 。 图像不是文本,因此这不是正确的选项。

不幸的是,System.IO命名空间中的类名存在严重问题。 StreamReader旨在读取\写入\到文本文件。 您应该像@goodwill建议的那样将FileStream用于二进制文件

你不能这样做….改为使用FileStream。

你不能使用字符串来读取二进制文件,据我所知,有些字符不会成功。

字符串用于表示文本。 他们擅长表达文字。 实际上非常好,因为它们支持Unicode并保护您免受各种典型的字符串处理错误的影响。

他们不善于表示二进制数据,因为这不是他们的设计目标。 正如您所提到的,字节数组要好得多。

这不是一个比另一个更好的问题,它只是适合目的和理解何时选择其中一个。 Text = string,binary = byte array或stream。

我注意到没有人回答实际问题。

将数据读入字符串时会丢失什么?

JPEG文件包含图片而不是单词。 该bicture具有二进制表示作为字节序列。 其中一些字节的值0x00也表示为NUL。 在字符串中,包含此值的字节被解释为标记字符串的结尾。 超过字符串结尾的数据被视为未使用的缓冲区并被忽略。

当您将字符串写入文件时,不包括第一个NUL之外的任何内容。 结果,该文件不是完整的二进制图像,并且被试图将其解释为JPEG的软件的validation逻辑拒绝。

因此,当您使用非文本数据加载字符串时,数据通常丢失。 这里的问题是您已经有效地进行了无效的类型转换,但是编译器和运行时都没有阻止您,结果是数据损坏。

它真的有什么好处?

好几件事。 正如其他人所说,字符串旨在包含文本。 在.NET中,字符串支持除普通旧ASCII之外的编码。 对文本操作也有广泛的支持。 在帮助中查找格式说明符 ,以获得字符串操作的壮观示例。

为什么C#字符串使用NUL作为字符串结尾?

这是遗留物。 NUL对其他任何东西都不是很好,这样做简化了在托管代码中进出编组字符串的过程。 出于同样的原因,BSTR做同样的事情。

字符串默认使用Unicode编码,unicode使用NUL字符作为控制字符,双NUL用于终止,单个NUL用于表示之前的ASCII字符。

因此,二进制数据无法加载到字符串中。