Создание байтового массива из потока

Я сделал версию Prototype этого:

String.prototype.strip = function() {
  var translate_re = /[öäüÖÄÜß ]/g;
  var translate = {
    "ä":"a", "ö":"o", "ü":"u",
    "Ä":"A", "Ö":"O", "Ü":"U",
    " ":"_", "ß":"ss"   // probably more to come
  };
    return (this.replace(translate_re, function(match){
        return translate[match];})
    );
};

Используйте как:

var teststring = 'ä ö ü Ä Ö Ü ß';
teststring.strip();

Это изменит строку на a_o_u_A_O_U_ss

836
задан huysentruitw 21 April 2017 в 17:08
поделиться

2 ответа

Это действительно зависит от того, можно ли доверять s.Length. Для многих потоков Вы просто не знаете, каким количеством там будут данные. В таких случаях - и перед.NET 4 - я использовал бы код как это:

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
}

С.NET 4 и выше, я использовал бы Stream.CopyTo , который в основном эквивалентен циклу в моем коде - создают эти MemoryStream, звонят stream.CopyTo(ms) и затем возвращаются ms.ToArray(). Задание сделано.

я должен, возможно, объяснить, почему мой ответ более длинен, чем другие. Stream.Read не гарантирует, что это считает все, относительно чего это просят. Если Вы читаете из сетевого потока, например, он может считать ценность одного пакета и затем возвратиться, даже если будет больше данных скоро. BinaryReader.Read будет продолжать идти до конца потока или Вашего указанного размера, но все еще необходимо знать, что размер запускается с.

вышеупомянутый метод будет продолжать читать (и скопировать в MemoryStream), пока он не исчерпает данные. Это тогда просит MemoryStream возвращать копию данных в массиве. Если Вы знаете, что размер для запуска с - или думает , Вы знаете размер, не будучи уверенными - можно создать MemoryStream, чтобы быть что размер для запуска с. Аналогично можно поместить проверку в конец, и если длина потока является тем же размером как буфер (возвращенный [1 115] MemoryStream.GetBuffer ) тогда, можно просто возвратить буфер. Таким образом, вышеупомянутый код не вполне оптимизирован, но по крайней мере будет корректен. Это не принимает на себя ответственности за закрытие потока - вызывающая сторона должна сделать это.

См. эта статья для большего количества информации (и альтернативная реализация).

1201
ответ дан Jon Skeet 21 April 2017 в 17:08
поделиться

Просто хочу отметить, что если у вас есть MemoryStream, у вас уже есть memorystream.ToArray () для этого.

Кроме того, если вы имеете дело с потоками неизвестных или разных подтипов и можете получить MemoryStream , вы можете использовать указанный метод для этих случаев и по-прежнему использовать принятый ответ для других, например :

public static byte[] StreamToByteArray(Stream stream)
{
    if (stream is MemoryStream)
    {
        return ((MemoryStream)stream).ToArray();                
    }
    else
    {
        // Jon Skeet's accepted answer 
        return ReadFully(stream);
    }
}
105
ответ дан 22 November 2019 в 21:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: