二进制文件可以作为文本读取吗
本文关键字:文本 读取 二进制文件 | 更新日期: 2023-09-27 18:19:44
虽然问题标题本身就很完整,但我将提供一些关于我如何解决这个问题的元信息。
对于SQL Server和MySQL,它对任何类型和大小的数据都很好,但最近我开始使用一个DBMS,该DBMS在表的每列中最多只允许64KB的数据。当列中存在二进制数据时,64KB的限制是有问题的。其他示例是-包含图像、音频、多媒体对象或地理空间数据的列。
您不会总是得到大小小于64KB的图像。BLOB不能简单地存储在这样的DBMS中。DBMS允许用户通过用C/C++编写函数并调用它们来增加其功能。但即使使用这些函数,我们每次调用最多也可以返回64KB的数据。
有人向我建议了一个变通方法——
将二进制数据存储在文件系统中,并为其存储标识符表列中的特定二进制数据。这样,当任何人请求该数据时,数据可以以块的形式发送回调用方每个大小为64KB
但后来出现了第二个限制,即数据只能作为以下数据类型之一从DBMS发送——char/varchar/integer/smallint/bigint/boolean/real。这个列表中最受欢迎的候选者是varchar(max),原因很明显(它是最长的)。
那么,二进制文件可以作为文本读取和发送吗与DBMS对话的客户端正在C#中开发。
将二进制文件块读取为文本然后发送该文本只有一个问题。问题是,转换后的文本不会返回创建该文本时使用的二进制文件。
在不提供链接的情况下,很容易理解在足够低的抽象级别上,所有文件都是"二进制"的,因为它们只包含一堆以二进制形式编码的数字。
但是,区分非常重要
- 文本文件,,其中所有数字都可以解释为表示人类可读文本的字符,以及
- 二进制文件、,其中包含的数据如果被解释为字符,则会产生不可打印的字符1
因此,我们可以读取一个二进制文件,该文件可能包含用于产生声音的字节组合,并且由于它是不可打印的,因此它将不可恢复地丢失。有用于移动光标位置的字节组合。一旦你击中一个,你就失去了定位。
转换为文本时,不仅任何控制字符都会丢失,整个可打印文本也不会就位,从而导致二进制文件出现混乱。
因此,二进制到文本到二进制的转换是有损耗的
替代方案
最常见的替代方法是将二进制数据转换为其十六进制表示,然后发送回等效于二进制数据的字符串。现在,一个字节的大小显然是1个字节。1个字符的大小也是1个字节,但以十六进制形式表示1个字节需要2个字符。换句话说,当你想检索1 GB的二进制文件时,你会得到2 GB的文本。
然而,当采用这种方法时,SoapHexBinary类提供了支持,它将十六进制字符串到二进制的转换减少到一个方法调用,如如何将Byte Array转换为十六进制字符串,反之亦然。
--------
没有被证明是更好的,但另一种方法如下:
- 创建一个字符串流(或类似于
string builder
的等效字符串流) - 选择任意字符(需要1个字节)作为分隔符
- 选择DBMS支持的最大可能的基元数字。设其大小为k字节。在我的DBMS中,它是
BIGINT
,它是一个固定大小为64位(8字节)的整数 - 一次读取二进制文件k字节,并创建等效的数值
- 在字符串流中插入以字符分隔的数值
- 当流/构建器的大小达到可能的最大值时,返回此字符串
在客户端,提取以字符分隔的字符串,将其转换为数值,从该值中获取字节,并将这些字节连接起来以重新创建二进制文件。
1在ASCII中,前32个字符是非打印控制字符,最初用于控制电传打字机的行为,使其执行诸如敲钟、后退一个字符、移动到新行以及将回车移动到行首等操作。在这32个控制字符中,通常只有换行符、回车符和水平制表符这三个字符出现在文本文件中