我有一个从Python 2转换的应用程序(其中字符串本质上是字节列表),我使用字符串作为方便的字节缓冲区。
我正在用Boo语言(类似Python的语法,在.NET上运行)重写一些代码,并且发现字符串具有固有的编码类型,例如ASCII,UTF-8等。大多数处理字节的信息是指字节数组,它们(显然)是固定长度的,这使得它们很难处理。
我显然可以从字符串中获取字节,但是有可能将某些字符扩展为多个字节,或者丢弃/更改127以上的字节等等。这很好,我完全理解这个的原因 - 但是会是什么对我来说,方便的是(a)保证不转换或丢弃字符的编码,以便我可以使用字符串作为方便的字节缓冲区,或者(b)某种类型的ByteString类,它提供了字符串类的便利。 (理想情况下是后者,因为它似乎不是一个黑客。)这些中的任何一个已经存在? (或者实现起来很简单?)
我知道System.IO.MemoryStream,但是每次创建其中一个然后必须在最后创建一个System.IO.StreamReader才能访问ReadToEnd()的前景似乎不太高效,这是对性能敏感的代码。
(我希望没有人介意我将其标记为C#,因为我觉得答案也可能适用于那里,并且C#用户可能对可能的解决方案有很好的了解。)
编辑:我刚刚发现了System.Text.StringBuilder - 再次,是否存在字节这样的事情?答案 0 :(得分:4)
Use the Latin-1 encoding as described in this answer。它将128-255范围内的值映射不变,当您想要将字节往返到字符时非常有用。
<强>更新强>
或者如果您想直接操作字节,请使用List<byte>
:
List<byte> result = ...
...
// Add a byte at the end
result.Add(b);
// Add a collection of bytes at the end
byte[] bytesToAppend = ...
result.AddRange(bytesToAppend);
// Insert a collection of bytes at any position
byte[] bytesToInsert = ...
int insertIndex = ...
result.InsertRange(insertIndex, bytesToInsert);
// Remove a range of bytes
result.RemoveRange(index, count);
... etc ...
我刚刚发现了System.Text.StringBuilder - 再次,是否存在字节这样的事情?
需要StringBuilder
类,因为常规字符串是不可变的,而List<byte>
为您提供了“StringBuilder for bytes”所能提供的所有内容。
答案 1 :(得分:2)
我建议你使用MemoryStream和GetBuffer()运算符来检索最终结果。字符串实际上是固定长度和不可变的,并且要向字符串添加或替换一个字节,需要将整个事物复制到新字符串中,这很慢。为了避免这种情况,你需要使用一个StringBuilder来分配内存,并在需要时将容量加倍,但是你也可以使用MemoryStream来代替类似的东西但是在字节上。
字符串中的每个元素都是一个char,实际上是两个字节,因为.NET字符串在内存中总是UTF-16,这意味着如果你决定在每个元素中只存储一个字节,你也会浪费内存。