2012-12-21 78 views
3
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); 

上述代碼將當前日期時間格式化爲長整型值,並將其傳遞給將其轉換爲壓縮十進制格式的方法。我知道上面的工作,因爲當我通過代碼的時候,字節數組對我所期望的所有字節都有正確的十六進制值。StringBuilder附加字節,無格式

但是,以上是我遇到的代碼,具體而言,我研究並發現字符串生成器.Append(byte)實際上爲該字節執行ToString()。在將字節添加到字符串時,它正在改變字節的值。問題是如何告訴StringBuilder將「字節」保持原樣並將其存儲在內存中,而不格式化/更改值。我知道還有一個.AppendFormat()有幾個重載使用IFormatProvider給如何格式化的東西很多很多選項,但我沒有看到任何方式告訴它不格式/改變/改變的價值數據。

+1

'問題是如何告訴StringBuilder將'byte'作爲原樣並將其存儲在內存中,而無需格式化/更改值。'嗯,你不能真的因爲一個StringBuilder代表一個可變的字符序列,但**一個字節不是一個字符**。如果知道編碼(推測爲ASCII),則可以將字節轉換爲字符。 –

回答

9

您可以將字節轉換爲字符:

sb.Append((char)b); 

你也可以使用一個ASCIIEncoding所有字節一次轉換:

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

非常感謝!這是一個真正的生活救星。這也應該防止轉換噸BSTR有任何問題,因爲它存儲爲一個ASCII值。我也可能有轉換實用程序做演員,但我喜歡你的解決方案轉換爲字符串。 – user1922299

+0

我使用了string s = Encoding.ASCII.GetString(packedDecValue)。這似乎工作,但在某些情況下,當我們將其添加到字符串生成器它仍然會亂碼字符串。從擴展ascii集合中獲取ASCII值的東西看,特別是我們遇到的值是{0x01,0x99,0x0c}。它作爲一個字符串從編碼中作爲一個字符串出現,但是當它被添加到字符串生成器時,它會被轉換爲其他字符。 Encoding.ASCII.GetString(packedDecValue)的值是「?\ f」,sb可能由於\?而損壞。 – user1922299

+0

從頭開始,我剛剛投票的下一個響應解決了這個問題,因爲0x99超出了0x00-0x7f的範圍,正在聲明它是夾持數據。所以對於打包的dec這個解決方案將無法工作。 – user1922299

1

如前所述,在一個統一的世界,字節(八位字節)不是字符。 CLR在內部使用Unicode字符,內部使用UTF-16編碼表示它們。 A StringBuilder構建一個UTF-16編碼的Unicode字符串。

然而,一旦你有了UTF-16字符串,你可以使用UTF-8或ASCIIEncoding對它進行重新編碼。但是,在這兩種情況下,代碼點0x0080和更高都不會保持原樣。

UTF-8使用2個八比特組作爲代碼點0x0080 – 0x07FF; 3個八位字節用於代碼點0x0800 – 0xFFFF等等。 http://en.wikipedia.org/wiki/UTF-8#Description

的ASCII編碼更糟糕的是:每the documentation,外面爲0x0000 – 0X007F碼點只是打發:

如果您使用由Encoding.ASCII屬性或 ASCIIEncoding構造,人物返回的默認編碼器在編碼操作執行之前,在該範圍之外被替換爲 問號(?)。

如果你需要發送的字節流毫髮無損,你最好使用System.IO.MemoryStream包裹在StreamReaderStreamWriter

然後,您可以通過其GetBuffer()方法或其ToArray()方法訪問MemoryStream的後備存儲。 GetBuffer()爲您提供了實際後備存儲的參考。但它可能包含分配但未使用的字節—,您需要檢查流的LengthCapacityToArray()分配一個新的數組並將實際的流內容複製到它中,所以您收到的數組引用是正確的長度。

+0

感謝您的背景資料。很高興知道,因爲我的編碼ascii應該工作正常,因爲我所有的值都應該在ascii編碼範圍內。然而,如果我正在做的事情,而不是將數字轉換爲壓縮十進制,它可能是一個問題... IE嘗試存儲可能的大值的原始二進制數據。 – user1922299

+0

看來我碰到了ASCII的代碼點。我仍然可以使用UTF-8進行編碼,或者我是否需要完全放棄使用stringbuilder並使用streamreader?查看當前最新更新的評論。 – user1922299

+0

有沒有辦法讓這個內存流/流閱讀器並將流轉換爲bstr? – user1922299