检查TStringStream的内容

检查TStringStream的内容,string,delphi,binary,String,Delphi,Binary,我在TStringStream中有一些好的或不太好的数据,或者它可以是任何TStream,我希望以最佳方式可视化,如果它包含文本,我希望将其显示为文本,如果不可能,我希望显示十六进制代码。我知道没有可靠的防弹方法可以说这是一个文本或二进制文件,但这不是目标,只是将其可视化以便调试 所以如果字符串 只有字符字符和代码,介于32和127之间,我可以 接受它作为一个回答。这很容易实现 如果没有,我会尝试将其转换为 Utf8String,我知道Utf8String有一种格式,所以我可以决定 它是否为有效

我在TStringStream中有一些好的或不太好的数据,或者它可以是任何TStream,我希望以最佳方式可视化,如果它包含文本,我希望将其显示为文本,如果不可能,我希望显示十六进制代码。我知道没有可靠的防弹方法可以说这是一个文本或二进制文件,但这不是目标,只是将其可视化以便调试

所以如果字符串

只有字符字符和代码,介于32和127之间,我可以 接受它作为一个回答。这很容易实现 如果没有,我会尝试将其转换为 Utf8String,我知道Utf8String有一种格式,所以我可以决定 它是否为有效的utf8字符串。所以我需要某种函数,它可以 告诉我是的,它可以是utf8string。如果我错了,谁在乎,这是否会是一个错误 不可读的文本,这不是问题,我也不能流利地阅读十六进制代码。 如果情况仍然不是这样,我想将其解释为一个宽边字符串,这是 最难的部分,因为我知道它没有任何格式,所以我需要猜一个 这里有很多,这需要最大的创造力。如果这完全是一项不可能完成的任务 跳过这一点。但是说我不期待汉字。 否则:显示十六进制代码。
我完全重写了我的问题,因为每个人都在评论这样一个事实,数据来自哪里,我应该如何定义协议,我也得到了有用的提示,谢谢,这并没有让我更接近于解决我的问题,希望在新问题中能更好地描述这一点。

我强烈建议定义一个协议并坚持它。例如,定义所有文本均为UTF8格式,以便在Delphi 7中使用UTF8Encode/UTF8Decode,在XE2中使用UTF8ToWideString可以节省带宽!,此外,每条消息都有一个标头,它定义了它是什么,例如二进制以及它的长度,因此您知道在数据之后,您可以将下一条消息或文本还原为UTF8。

您无法实现防弹验证。在您有一些外部限制之前,什么可以作为字符串传递-WideString的任何字符在AnsiString中都是有效的字符对。因此,您必须在字符串之前传递一些标记

对于unicode字符串,通常会在流开始时发送一个特殊的字母:这不是防弹的,但是对于第一个和第二个字符,发送这种字母的几率非常低——尽管仍然有可能。 您可以约定,前两个字节将是Windows代码页,然后使用TEncoding将字节进一步转换为字符串。然而,这将使未来与非Windows系统的交互变得相当困难。 您可以在主加载之前传递作为一个AnsiString标记,如。该标记只使用7位ASCII值,所以从流中获取它是安全的。然而,这些字符集名称中有很多同义词,因此您必须查询一些字典中的同义词名称。 所以如果字符串

•只有字符字符和代码,介于32和127之间,我可以将其视为AnsiString。这很容易实现

对。但是,128到255之间的字符值(也称ANSI/MBCS字符)也可以存储在AnsiString中并以可视方式显示,但您必须知道这些值所属的原始字符集。在D2009+的情况下,可以将值存储到RawByteString中,并使用SetCodePage函数将适当的代码页与字符串关联。这样,当您在代码中传递字符串时,可以正确解释字符。如果您不关心Unicode格式之外的非ASCII字符,那么您可以忽略这一点

•如果不是,我会尝试将其转换为Utf8String,因为我知道Utf8String有一种格式,所以我可以决定它是否是有效的utf8字符串。所以我需要某种函数,它可以告诉我是的,它可以是一个utf8string

要检查数据是否为有效的UTF-8字符串,您可以使用Win32 API Windows.MultiByteToWideChar函数,或仅使用Embarcadero的System.LocalECharstoinicode函数XE和更高版本。指定CP_UTF8 65001代码页、MB_ERR_INVALID_CHARS标志和nil输出缓冲区。如果数据是有效的UTF-8字符串,则函数将返回数据在实际解码时可以产生的UTF-16字符数。否则,函数将失败,并出现错误\u NO\u UNICODE\u翻译错误代码

仅D2009及更高版本的另一个选项是使用SysUtils.TEncoding.UTF8类的GetCharCount方法来计算相同数量的UTF-16字符

•如果仍然不是这样,我想将其解释为宽字符串,这是最困难的部分,因为我知道它没有任何格式

是的,当然有-UTF-16,它和UTF-8一样是一种定义格式。事实上,UTF-16有两种风格,小端和大端

要检查数据是否为有效的UTF-16 little-endian纯字符串,可以使用Win32 API Windows.WideChart多字节函数 n、 或Embarcadero的System.UnicodeolCaleChars函数XE和更高版本。指定CP_UTF8 65001代码页、WC_ERR_INVALID_CHARS标志和nil输出缓冲区。如果数据是有效的UTF-16LE字符串,则函数将返回数据在实际编码时可以产生的UTF-8字节数。否则,函数将失败,并出现错误\u NO\u UNICODE\u翻译错误代码

仅D2009及更高版本的另一个选项是使用SysUtils.TEncoding.Unicode little endian或SysUtils.TEncoding.BigendiaUnicode类的GetByteCount方法来计算相同数量的UTF-8字节

所以我需要在这里猜很多


不,你没有。对于UTF-8和UTF-16,不涉及猜测。它们是定义良好的标准化格式,设计用于在不丢失任何数据的情况下相互转换。

二进制缓冲区可能包含32到127之间的值。你为什么不决定一个双方都同意遵守的协议呢?这就是所有沟通的方式。发送一团团这样或那样的东西,然后猜测里面装的是什么,这就是疼痛的处方。如果您想发送文本,并且需要支持Unicode,请使用UTF8。@DavidHeffernan我想要它。但实际上,此功能主要用于调试。如果是原始二进制,我会打印十六进制代码……我不明白。你不知道文本是用二进制表示的吗。计算机上的一切都是二进制的。@DavidHeffernan是的,我当然知道。也许我不够清楚,我只是想为调试建议转储流量,我可以每次将其转换为十六进制,而不是打印示例48656C6F,当我的消息中有Hello时,字符串看起来更友好,不是吗,但是当消息中没有字符串时,我会打印十六进制代码,因为它比错误转换的文本更有意义。如果你明白计算机上的所有内容都是二进制的,你就会明白你无法可靠地将文本与其他内容区分开来。TStringStream在D2009中启用了TEncoding,因此你可以使用TStringStream.Create…,TEncoding.UTF8而不是UTF8ToWideString。谢谢,每个人都提出了这样的建议,我接受了这个建议,但真正的问题不是这样。我会更新我的问题。目标不是防弹验证,只是为了调试。谢谢你的时间。然后你可以随时发布一些常量,并检查它是否像ABCD或A0B0C0D0一样-但是就像BOM一样,这需要修改程序。我完全重写了问题,见上文。这是误导。