StringBuilder добавляет байт без форматирования
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);
Приведенный выше код берет текущее время даты, форматирует его в длинное значение и передает его методу, который преобразует его в упакованный десятичный формат. Я знаю, что вышесказанное работает, поскольку, когда я выполняю код, массив байтов имеет правильные шестнадцатеричные значения для всех байтов, которые я ожидаю.
Однако выше приведен код, с которым у меня возникают проблемы, в частности, я исследовал и обнаружил, что строитель строк .Append(byte)
на самом деле делает ToString()
для этого байта. Который изменяет значение байта при добавлении его в строку. Вопрос в том, как мне StringBuilder
взять "байт" как есть и сохранить его в памяти без форматирования / изменения значения. Я знаю, что есть также .AppendFormat()
который имеет несколько перегрузок, которые используют IFormatProvider
дать много-много опций о том, как форматировать вещи, но я не вижу способа сказать это НЕ форматировать / изменять / изменять значение данных.
2 ответа
Вы можете преобразовать байт в символ:
sb.Append((char)b);
Вы также можете использовать ASCIIEncoding
преобразовать все байты одновременно:
string s = Encoding.ASCII.GetString(packedDecValue);
sb.Append(s);
As noted, in a Unicode world, bytes (octets) are not characters. The CLR works with Unicode characters internally and internally represents them in the UTF-16 encoding. StringBuilder
builds a UTF-16 encoded Unicode string.
Once you have that UTF-16 string, however, you can re-encode it, using, say UTF-8 or the ASCIIEncoding. However, in both of those, code points 0x0080 and higher will not be left as-is.
UTF-8 uses 2 octets for code points 0x0080–0x07FF; 3 octets for code points 0x0800–0xFFFF and so on. http://en.wikipedia.org/wiki/UTF-8
The ASCII encoding is worse: per the documentation, code points outside 0x0000–0x007F are simply chucked:
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.
Если вам нужно отправить поток октетов в целости и сохранности, лучше использовать System.IO.MemoryStream
завернутый в StreamReader
а также StreamWriter
,
Вы можете получить доступ к MemoryStream
Поддерживает магазин через свой GetBuffer()
метод или его ToArray()
метод. GetBuffer()
дает вам ссылку на фактический резервный магазин. Однако он, вероятно, содержит выделенные, но неиспользуемые байты - вам нужно проверить поток Length
а также Capacity
, ToArray()
выделяет новый массив и копирует в него фактическое содержимое потока, поэтому полученная вами ссылка на массив имеет правильную длину.