Класс String без кодировки для обработки байтов?(Или альтернативный подход) - PullRequest
1 голос
/ 21 апреля 2011

У меня есть приложение, преобразованное из Python 2 (где строки, по сути, являются списками байтов), и я использую строку в качестве удобного буфера байтов.

Я переписываю часть этого кода на языке Boo(Python-подобный синтаксис, работает на .NET), и я обнаружил, что строки имеют встроенный тип кодирования, такой как ASCII, UTF-8 и т. Д. Большая часть информации, касающейся байтов, относится к массивам байтов, которые (по-видимому,) фиксированной длины, что делает их довольно неудобными для работы.

Я, очевидно, могу получить байты из строки, но с риском расширения некоторых символов до нескольких байтов или отбрасывания / изменения байтов выше 127 и т. д. ЭтоЭто хорошо, и я полностью понимаю причины этого, но мне может пригодиться (а) кодировка, которая не гарантирует преобразование или отбрасывание символов, так что я могу использовать строку в качестве удобного байтового буфера, или (б)какой-то класс ByteString, который дает удобство строкового класса.(В идеале последнее, так как это кажется менее взломанным.) Кто-нибудь из них уже существует?(Или тривиально реализовать?)

Я знаю о System.IO.MemoryStream, но есть перспектива создания одного из них каждый раз, а затем создание System.IO.StreamReader в конце просто дляполучить доступ к ReadToEnd () не кажется очень эффективным, и это в чувствительном к производительности коде.

(я надеюсь, никто не возражает, что я пометил это как C #, так как я чувствовал, что ответы, вероятно, применимы и там,и что пользователи C # могут иметь хорошее представление о возможных решениях.)

РЕДАКТИРОВАТЬ: я также только что обнаружил System.Text.StringBuilder - опять же, есть ли такая вещь для байтов?

Ответы [ 2 ]

4 голосов
/ 21 апреля 2011

Используйте кодировку Latin-1, как описано в этом ответе .Он отображает значения в диапазоне от 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 для байтов».

2 голосов
/ 21 апреля 2011

Я бы предложил использовать MemoryStream в сочетании с оператором GetBuffer () для получения конечного результата.Строки на самом деле имеют фиксированную длину и неизменны, и чтобы добавить или заменить один байт в строке, необходимо скопировать все это в новую строку, что довольно медленно.Чтобы избежать этого, вам нужно будет использовать StringBuilder, который выделяет память и удваивает емкость, когда это необходимо, но тогда вы также можете использовать MemoryStream вместо этого, который выполняет аналогичные действия, но с байтами.является символом и фактически представляет собой два байта, потому что строки .NET всегда имеют UTF-16 в памяти, что означает, что вы также будете тратить впустую память, если решите хранить только один байт в каждом элементе.

...