简体   繁体   English

StringBuilder追加没有格式化的字节

[英]StringBuilder append byte without formatting

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);

The above code takes the current date time, formats it into a long value and passes that to a method which converts it to a packed decimal format. 上面的代码获取当前日期时间,将其格式化为long值并将其传递给将其转换为压缩十进制格式的方法。 I know that the above works since when I step though the code the byte array has the correct Hex values for all of the bytes that I am expecting. 我知道上面的工作是因为当我逐步执行代码时,字节数组对于我期望的所有字节都具有正确的十六进制值。

However the above is the code I am having issues with, specifically I have researched and found that the string builder .Append(byte) actually does a ToString() for that byte. 但是上面是我遇到问题的代码,特别是我已经研究过并发现字符串生成器.Append(byte)实际上.Append(byte)执行ToString() Which is altering the value of the byte when it adds it to the string. 当它将字节添加到字符串时,这会改变字节的值。 The question is how do I tell the StringBuilder to take the 'byte' as is and store it in memory without formatting/altering the value. 问题是如何告诉StringBuilder按原样采用'byte'并将其存储在内存中而不格式化/更改值。 I know that there is also a .AppendFormat() which has several overloads which use the IFormatProvider to give lots and lots of options on how to format things but I don't see any way to tell it to NOT format/change/alter the value of the data. 我知道还有一个.AppendFormat()有几个重载使用IFormatProvider提供了很多关于如何格式化的选项,但我没有看到任何方法告诉它不格式化/改变/改变数据的价值。

You can cast the byte to a char: 您可以将字节转换为char:

sb.Append((char)b);

You can also use an ASCIIEncoding to convert all the bytes at once: 您还可以使用ASCIIEncoding一次转换所有字节:

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

As noted, in a Unicode world, bytes (octets) are not characters. 如上所述,在Unicode世界中,字节(八位字节)不是字符。 The CLR works with Unicode characters internally and internally represents them in the UTF-16 encoding. CLR在内部使用Unicode字符,在内部以UTF-16编码表示它们。 A StringBuilder builds a UTF-16 encoded Unicode string. StringBuilder构建UTF-16编码的Unicode字符串。

Once you have that UTF-16 string, however, you can re-encode it, using, say UTF-8 or the ASCIIEncoding. 但是,一旦有了UTF-16字符串,就可以使用UTF-8或ASCIIEncoding重新编码它。 However, in both of those, code points 0x0080 and higher will not be left as-is. 但是,在这两个代码点中,代码点0x0080和更高版本将不会保持原样。

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

The ASCII encoding is worse: per the documentation , code points outside 0x0000–0x007F are simply chucked: ASCII编码更糟糕:根据文档 ,0x0000-0x007F以外的代码点被简单地删除:

If you use the default encoder returned by the Encoding.ASCII property or the ASCIIEncoding constructor, characters outside that range are replaced with a question mark (?) before the encoding operation is performed. 如果使用Encoding.ASCII属性或ASCIIEncoding构造函数返回的默认编码器,则在执行编码操作之前,该范围之外的字符将替换为问号(?)。

If you need to send a stream of octets unscathed, you are better off using a System.IO.MemoryStream wrapped in a StreamReader and StreamWriter . 如果您需要发送未受损害的八位字节流,最好使用StreamReaderStreamWriter中包含的System.IO.MemoryStream

You can then access the MemoryStream 's backing store via its GetBuffer() method or its ToArray() method. 然后,您可以通过其GetBuffer()方法或其ToArray()方法访问MemoryStream的后备存储。 GetBuffer() gives you a reference to the actual backing store. GetBuffer()为您提供实际后备存储的引用。 However it likely contains alloated, but unused, bytes — you need to check the stream's Length and Capacity . 但是它可能包含已分配但未使用的字节 - 您需要检查流的LengthCapacity ToArray() allocates a new array and copies the actual stream content into it, so the array reference you recieve is the correct length. ToArray()分配一个新数组并将实际流内容复制到其中,因此您收到的数组引用是正确的长度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM