Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Encoding.UTF8将字节弄乱[]_C#_Utf 8_Character Encoding - Fatal编程技术网

C#Encoding.UTF8将字节弄乱[]

C#Encoding.UTF8将字节弄乱[],c#,utf-8,character-encoding,C#,Utf 8,Character Encoding,我面临着一个非常奇怪的问题,我有byte[],当我将它传递给Convert.UTF8.GetString(byte[]bytes)方法时,系统编码会弄乱我的字节,只将几个特殊字节(我在系统中用作标记)替换为一些三字符字符串表示 [0] 70 byte [1] 49 byte [2] 45 byte [3] 86 byte [4] 49 byte [5] 253 byte <-- Special byte [6] 70 byte [7] 49 byte [8] 45

我面临着一个非常奇怪的问题,我有byte[],当我将它传递给Convert.UTF8.GetString(byte[]bytes)方法时,系统编码会弄乱我的字节,只将几个特殊字节(我在系统中用作标记)替换为一些三字符字符串表示

[0] 70  byte
[1] 49  byte
[2] 45  byte
[3] 86  byte
[4] 49  byte
[5] 253 byte     <-- Special byte
[6] 70  byte
[7] 49  byte
[8] 45  byte
[9] 86  byte
[10]50  byte
[11]253 byte     <-- Special byte
[12]70  byte
[13]49  byte
[14]45  byte
[15]86  byte
[16]51  byte
实际值不应具有'�' 因为这意味着它无法编码这些特殊字节并将其替换为'�'. 无论如何,我都可以解决这个问题,即转换为字符串,并将特殊字节表示形式保留为单个字符

我有以下的特殊字节,我正试图使用它们作为标记

byte AM = (byte) 254
byte VM = (byte) 253
byte SM = (byte) 252 
您的帮助和意见将不胜感激

谢谢

--


Sheeraz

不能在UTF-8字符串中使用这些特殊值作为标记,因为根据UTF-8,该字符串最终无效

您可以偷偷地插入它们,然后在将数据输入UTF-8感知代码(如
Encoding.GetString
)之前将它们取出,但这并不是一个好主意,因为它是偷偷的(这让那些还不知道那里发生了什么伏都教的人感到困惑,因此非常适得其反)


更明智的选择是在字符串中简单地插入“特殊”UTF-8编码字符。这在技术上要求(特别是如果你选择了一个编码为1字节的字符,因为这些字符也很可能出现在你的实际有效负载中),你还需要想出一个方案,当这些字符自然出现在你的有效负载中时,转义这些字符。

数据只是标记之间的UTF-8,因此,如果是我,我将首先提取分隔部分,然后UTF-8分别解码每个部分,即通过
字节[]
读取二进制数据中的标记,给您3个二进制块(70,49,45,86,49;70,49,45,86,50;70,59,45,86,51)然后将其解码为3个字符串。无法对整个二进制序列进行UTF-8解码,因为它不是有效的UTF-8

然而,就我个人而言,在这里使用分隔符是危险的;我可能会选择长度前缀方法,这样

  • 我知道我没有意外地将分隔符和真实数据混为一谈
  • 我可以比逐字节更有效地处理它
例如,如果我们使用“varint”长度前缀,则将是:

05,70,49,45,86,49,05,70,49,45,86,50,05,70,59,45,86,51
其中
05
是我们解释为5字节的“可变”长度;这意味着我们可以很好地处理:

// pseude code
while(!EOF) {
    int len = ReadVarint();
    var blob = ReadBytes(len);
    string s = Utf8Decode(blob);
    // ...
}

+1如果您需要这样的标记,那么您可以在Unicode内部的某个位置选择一个字符来替代,例如在某个专用范围内,然后使用这些字符的有效UTF-8编码作为标记。但它们每个都将超过一个字节。或者提前将标记周围的字节流切碎,然后一次将每个有效部分转换为Unicode,但您需要小心,不要使用这些字节实际拾取真正的UTF-8编码,也就是说,您实际上是在编写自己的解码器。谢谢。。。我必须手动执行,因为要求所有内容都以UTF-8编码,因为我的DB仅为UTF-8。我现在不把任何东西转换成字符串,只处理字节。@SJunejo k,但请注意:您当前的策略不是UTF-8。你的数据库完全有权向你爆炸。
// pseude code
while(!EOF) {
    int len = ReadVarint();
    var blob = ReadBytes(len);
    string s = Utf8Decode(blob);
    // ...
}