837 votos

Crear una matriz de bytes de un arroyo

¿Cuál es el método preferido para la creación de una matriz de bytes de una secuencia de entrada?

Aquí está mi actual solución con .NET 3.5.

Stream s;
byte[] b;

using (BinaryReader br = new BinaryReader(s))
{
    b = br.ReadBytes(s.Length);
}

¿Es todavía una idea mejor para leer y escribir en trozos de la corriente?

1203voto

Jon Skeet Puntos 692016

Realmente depende de si o no usted puede confiar s.Length. Para muchos arroyos, solo que usted no sabe la cantidad de datos que habrá. En tales casos, debería utilizar un código como este:

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();
    }
}

EDIT: tal vez debería explicar por qué mi respuesta es más largo que los demás. Stream.Read no es garantía de que se va a leer todo lo que pidió. Si usted está leyendo de una red de flujo, por ejemplo, se puede leer uno de los paquetes de la pena y, a continuación, volver, incluso si hay más datos pronto. BinaryReader.Read va a seguir hasta el final de la corriente o de su tamaño especificado, pero usted todavía tiene que saber el tamaño para empezar.

El método anterior se sigue leyendo (y copiando en un MemoryStream) hasta que se acabe de datos. A continuación, le pide MemoryStream a devolver una copia de los datos en una matriz. Si usted sabe el tamaño para empezar - o piensa que usted sabe el tamaño, sin estar seguro de que usted puede construir MemoryStream a ser de ese tamaño para empezar. Asimismo, usted puede poner una marca de verificación en la final, y si la longitud de la secuencia es el mismo tamaño del búfer (devuelto por MemoryStream.GetBuffer) a continuación, puedes devolver el búfer. Así el código de arriba no está muy optimizado, pero al menos será correcta. No se asume ninguna responsabilidad por el cierre de la secuencia de la llamada se debería hacer.

Consulte este artículo para obtener más información (y una implementación alternativa).

672voto

Nathan Phillips Puntos 2849

Mientras que la respuesta de Jon es correcta, está reescribiendo código que ya existe en CopyTo. Así que para la solución de .net 4 uso Sandip, pero para la versión anterior de .net usa respuesta de Jon. Código de Sandip mejoraría por uso de "utilizar" como excepciones en CopyTo son, en muchas situaciones, muy probables y dejarían el MemoryStream no eliminado.

public static byte[] ReadFully(Stream input)
{
    using (MemoryStream ms = new MemoryStream())
    {
        input.CopyTo(ms);
        return ms.ToArray();
    }
}

101voto

Fernando Neira Puntos 1049

Sólo quiero señalar que en caso de que tengas un MemoryStream ya tiene memorystream.ToArray() para eso.

Además, si estás tratando con las secuencias de desconocido o diferentes subtipos y usted puede recibir un MemoryStream , puede transmitir dicho método para aquellos casos y todavía utilizan la respuesta aceptada por los demás, así:

    public static byte[] StreamToByteArray(Stream stream)
    {
        if (stream is MemoryStream)
        {
            return ((MemoryStream)stream).ToArray();                
        }
        else
        {
            // Jon Skeet's accepted answer 
            return ReadFully(stream);
        }
    }

63voto

Sandip Patel Puntos 287
MemoryStream ms = new MemoryStream();
file.PostedFile.InputStream.CopyTo(ms);
var byts = ms.ToArray();
ms.Dispose();

49voto

Alex Wheat Puntos 928

Sólo mis centavos par la práctica que a menudo utilizo es organizar los métodos así como ayudante de encargo

public static class StreamHelpers
{
    public static byte[] ReadFully(this Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }
}

agregar el espacio de nombres en el archivo config y utilizarlo en cualquier lugar que desee

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X