StringBuilder追加没有格式化的字节

时间:2012-12-21 19:04:27

标签: c# stringbuilder iformatprovider

DateTime todayDateTime = DateTime.Now;
StringBuilder todayDateTimeSB = new StringBuilder("0");
todayDateTimeSB.Append(todayDateTime.ToString("MMddyyyy"));
long todayDateTimeLongValue = Convert.ToInt64(todayDateTimeSB.ToString());
// convert to byte array packed decimal
byte[] packedDecValue = ToComp3UsingStrings(todayDateTimeLongValue); 
// append each byte to the string builder
foreach (byte b in packedDecValue)
{
    sb.Append(b); // bytes 56-60
}
sb.Append(' ', 37);

上面的代码获取当前日期时间,将其格式化为long值并将其传递给将其转换为压缩十进制格式的方法。我知道上面的工作是有效的,因为当我逐步执行代码时,字节数组对于我期望的所有字节都有正确的十六进制值。

但是上面是我遇到问题的代码,特别是我已经研究过,发现字符串构建器.Append(byte)实际上为该字节做了ToString()。当它将字节添加到字符串时,这会改变字节的值。问题是如何告诉StringBuilder按原样取出'byte'并将其存储在内存中而不格式化/更改值。我知道还有一个.AppendFormat()有几个重载使用IFormatProvider给出了很多关于如何格式化的选项,但是我没有看到任何方法告诉它不格式化/更改/更改数据的值。

2 个答案:

答案 0 :(得分:9)

您可以将字节转换为char:

sb.Append((char)b);

您还可以使用ASCIIEncoding一次转换所有字节:

string s = Encoding.ASCII.GetString(packedDecValue);
sb.Append(s);

答案 1 :(得分:1)

如上所述,在Unicode世界中,字节(八位字节)不是字符。 CLR在内部使用Unicode字符,在内部以UTF-16编码表示它们。 StringBuilder构建UTF-16编码的Unicode字符串。

然而,一旦你有了UTF-16字符串,就可以使用UTF-8或ASCIIEncoding重新编码它。但是,在这两个代码点中,代码点0x0080和更高版本不会保持原样。

UTF-8使用2个八位字节代码点0x0080-0x07FF;代码点为0x0800-0xFFFF的3个八位字节,依此类推。 http://en.wikipedia.org/wiki/UTF-8#Description

ASCII编码更糟糕:根据the documentation,0x0000-0x007F之外的代码点只是简单地被删除了:

  

如果使用Encoding.ASCII属性返回的默认编码器或   ASCIIEncoding构造函数,该范围之外的字符将替换为   执行编码操作之前的问号(?)。

如果您需要毫发无损地发送八位字节流,最好使用System.IO.MemoryStreamStreamReader中包含的StreamWriter

然后,您可以通过其MemoryStream方法或其GetBuffer()方法访问ToArray()的后备存储。 GetBuffer()为您提供实际后备存储的引用。但是,它可能包含已分配但未使用的字节 - 您需要检查流LengthCapacityToArray()分配一个新数组并将实际流内容复制到其中,因此您收到的数组引用是正确的长度。