【问题标题】:Can a binary file be read as text?二进制文件可以作为文本读取吗?
【发布时间】:2015-10-28 20:16:45
【问题描述】:

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


使用 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),原因很明显(它是最长的)。

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

【问题讨论】:

    标签: c# varchar binary-data


    【解决方案1】:

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

    如果没有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 个字节并创建等效的数值。
    • 将数值插入字符串流,以字符分隔。
    • 当流/构建器的大小达到可能的最大值时,返回此字符串。

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


    1在 ASCII 中,前 32 个字符是非打印控制字符,最初用于控制电传打字机的行为,使其执行诸如响铃之类的事情,后退一个字符,移动到新行,然后将回车移动到行首。在这 32 个控制字符中,只有换行符、回车符和水平制表符这三个通常出现在文本文件中。

    【讨论】:

    • 您在替代方案中忽略但使用非常广泛的一件事是 Base64 编码,它使您的大小增加了 4/3 (~1.333x),而十六进制编码的大小是 2x。它也可以通过Convert.ToBase64StringConvert.FromBase64String 简化为单个调用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 2017-06-11
    • 2023-03-13
    • 2020-10-25
    • 1970-01-01
    • 2010-12-30
    • 2021-11-18
    相关资源
    最近更新 更多