我在TStringStream
中有一些很好或不太好的数据(或者它可以是任何TStream
),我希望以最佳方式可视化,如果它包含文本,我会喜欢将其显示为文本,如果不可能,我想显示十六进制代码。我知道没有防弹方式可靠地说是文本或二进制文件,但这不是目标,只是将其可视化以用于调试建议。
所以如果是字符串
Chars
,代码在32到127之间,我可以
接受它为AnsiString
。 很容易实现 Utf8String
,据我所知Utf8String
有格式,所以我可以决定是
它是否是一个有效的utf8字符串。所以我需要某种功能
告诉我是的,它可以是一个utf8string。如果我错了,谁在乎,如果它是一个
不可读的文本,这不是问题,我也不能流利地阅读十六进制代码。我完全重写了我的问题,因为每个人都在评论这样一个事实:数据来自哪里,我应该如何定义一个协议(我也得到了有用的提示,谢谢你),这让我更加接近解决我的问题,希望在新问题中有更好的描述。
答案 0 :(得分:1)
所以如果是字符串
•只有字符Chars,代码在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.LocaleCharsToUnicode()
函数(仅限XE及更高版本)。指定CP_UTF8
(65001)代码页,MB_ERR_INVALID_CHARS
标志和nil
输出缓冲区。如果数据是有效的UTF-8字符串,则该函数将返回数据在实际解码时可以生成的UTF-16字符数。否则,该函数将失败并显示ERROR_NO_UNICODE_TRANSLATION
错误代码。
另一个选项(仅限D2009及更高版本)是使用GetCharCount()
类的SysUtils.TEncoding.UTF8
方法计算相同数量的UTF-16字符。
•如果情况仍然不是这样,我想把它解释为一个宽字符串,这是最难的部分,因为我知道它没有任何格式
是的,当然它确实如此 - UTF-16,它与UTF-8一样定义了格式(实际上,有两种口味的UTF-16,小端和大端)。
要检查数据是否是有效的UTF-16(仅限小端)字符串,您可以使用Win32 API Windows.WideCharToMultiByte()
函数或Embarcadero的System.UnicodeToLocaleChars()
函数(仅限XE及更高版本)。指定CP_UTF8
(65001)代码页,WC_ERR_INVALID_CHARS
标志和nil
输出缓冲区。如果数据是有效的UTF-16LE字符串,则该函数将返回数据在实际编码时可以生成的UTF-8字节数。否则,该函数将失败并显示ERROR_NO_UNICODE_TRANSLATION
错误代码。
另一个选项(仅限D2009及更高版本)是使用GetByteCount()
(小端)或SysUtils.TEncoding.Unicode
类的SysUtils.TEncoding.BigEndianUnicode
方法来计算相同数量的UTF-8字节。
所以我需要在这里猜测很多
不,你没有。对于UTF-8和UTF-16,不需要猜测。它们是定义明确的标准化格式,它们旨在相互之间进行转换,而不会丢失任何数据。
答案 1 :(得分:0)
我强烈建议定义协议并坚持下去。例如,定义所有文本都是UTF8,所以在Delphi 7中你可以使用UTF8Encode / UTF8Decode和XE2 UTF8ToWideString(节省带宽!),并且每个消息都有一个标题来定义它是什么(例如二进制)它有多长,所以你知道在数据之后你可以恢复为UTF8以获得下一条消息或文本。
答案 2 :(得分:0)
您无法实施防弹验证。除非你有一些外部限制,可以作为字符串传递 - WideString的任何字符也都是AnsiString中的有效字符对。所以你必须在字符串之前传递一些标记。