二进制文件可以作为文本读取吗?

Can a binary file be read as text?

虽然问题标题本身是完整的,但我将提供一些关于我如何解决这个问题的元信息。


使用 SQL 服务器和 MySQL 任何类型和任何大小的数据都很好,但最近我开始使用最多只允许 64 KB 的 DBMS每列数据一个table。当列中有二进制数据时,64 KB 的限制是有问题的。其他示例是 - 包含图像或音频或多媒体 object 或地理空间数据的列。

您不会总是获得小于 64 KB 的图像。 BLOB 不能简单地存储在这样的 DBMS 中。 DBMS 允许用户通过在 C/C++ 中编写函数并调用它们来增加其功能。但是,即使使用这些函数,我们也可以 return 每次调用最多 64 KB 数据。

有人建议我解决方法 -

store the binary data on file system and store an identifier to that particular binary data in the table's column. This way, when anyone requests that data, the data can be sent back to the caller in chunks of 64 KB size each.

但是随后出现了第二个限制,即数据只能作为以下数据类型之一从 DBMS 发送 - char / varchar / integer / smallint / bigint / boolean / real。此列表中最受欢迎的候选者是 varchar(max),原因很明显(它是最长的)。

那么,二进制文件可以作为文本读取和发送吗?正在用 C# 开发与 DBMS 通信的客户端。

将二进制文件块作为文本读取然后发送该文本只有一个问题。这个问题是转换后的文本 return 与创建此文本的二进制文件不同。

不用 providing links 就可以很简单地理解 在足够低的抽象层次上,所有文件都是 "binary",因为它们只包含一堆编码的数字二进制形式。

但是,区分非常重要

  • 文本文件其中所有数字都可以解释为代表人类可读文本的字符,以及
  • 二进制文件其中包含的数据如果被解释为字符,将产生不可打印的字符1

因此,我们可能会读取一个二进制文件,其中可能包含用于产生声音的字节组合,并且因为它是不可打印的,所以它将不可恢复地丢失。有用于移动光标位置的字节组合。一打就丢位

不仅在转换为文本时会丢失任何控制字符,而且整个可打印文本也不会就位,从而导致二进制文件出现乱码。

因此,二进制到文本到二进制的转换是有损的。


备选方案?

最常见的替代方法是将二进制数据转换为其十六进制表示形式,然后发回相当于二进制数据的字符串。现在,一个字节的大小显然是 1 个字节。 1 个字符的大小也是 1 个字节,但需要 2 个字符才能以十六进制形式表示 1 个字节。换句话说,当您想要检索 1 GB 的二进制文件时,您会得到 2 GB 的文本。

但是,当采用这种方法时,得到了 SoapHexBinary class which reduces the hexadecimal string to binary conversion down to one method call, demonstrated in this answer to How do you convert Byte Array to Hexadecimal String, and vice versa.

的支持

--------

未证明更好,但另一种方法如下:

  • 创建字符串流(或类似 string builder 的字符串流)。
  • 选择任意字符(占用 1 个字节)作为分隔符。
  • 选择 DBMS 支持的最大可能的原始数字。让它的大小为 k 字节。在我的 DBMS 中,它是 BIGINT,它是一个固定大小为 64 位(8 字节)的整数。
  • 一次读取二进制文件 k 个字节并创建等效数值。
  • 将数值插入字符串流,以字符分隔。
  • 当 stream/builder 的大小达到可能的最大值时,return 这个字符串。

在客户端,提取 char 分隔的字符串,将它们转换为数值,从该值中获取字节并将这些字节连接起来以重新创建二进制文件。


1在 ASCII 中,前 32 个字符是非打印控制字符,最初用于控制电传打字机的行为,导致它做诸如敲响铃声、后退一个字符、移动到新行以及将马车移动到行首等操作。在这 32 个控制字符中,只有三个,换行符、回车符 return 和水平制表符通常出现在文本文件中。