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

时间:2015-10-28 20:16:45

标签: c# varchar binary-data

虽然问题标题本身已经完成,但我会提供一些关于如何解决此问题的元信息。

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

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

有人建议我解决方法 -

  

将二进制数据存储在文件系统上并存储标识符   表格列中的特定二进制数据。这样,任何人   请求数据,数据可以以块的形式发送回调用者   每个64 KB大小。

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

那么,可以读取二进制文件并以文本形式发送吗?与CMS通信的客户端正在用C#开发。

1 个答案:

答案 0 :(得分:3)

将二进制文件块作为文本读取然后发送该文本只有一个问题。问题是转换后的文本不会返回从中创建此文本的二进制文件。

如果没有providing links 处于足够低的抽象层次,那么所有文件都是“二进制”的,它们只包含一堆以二进制形式编码的数字。

然而,区分

非常重要
  • 文本文件其中所有数字都可以解释为代表人类可读文字的字符
  • 二进制文件包含数据,如果解释为字符,则会生成不可打印的字符 1

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

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

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

替代?

最常见的替代方法是将二进制数据转换为十六进制表示形式,然后发回该字符串等效的二进制数据。现在,一个字节的大小显然是1个字节。 1个字符的大小也是1个字节,但是需要2个字符来表示十六进制形式的1个字节。换句话说,如果要检索1 GB二进制文件,则会获得2 GB的文本。

然而,采用这种方法时,SoapHexBinary class支持将十六进制字符串缩减为二进制转换,直至一个方法调用,在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 字节并创建等效的数值。
  • 将数值插入字符串流,char delimited。
  • 当流/构建器的大小达到最大值时,返回此字符串。

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

1 在ASCII中,前32个字符是非打印控制字符,最初用于控制电传打字机的行为,导致它发出铃声,备份一个字符,移动到一个新行,并将滑架移动到该行的开头。在这32个控制字符中,只有三个,换行符,回车符和水平制表符通常位于文本文件中。