net example convertir convert array c# inputstream bytearray

c# - example - stream to byte array vb net



¿Cómo convertir un Stream en un byte[] en C#? (12)

Esta pregunta ya tiene una respuesta aquí:

¿Existe una forma o método simple para convertir un Stream en un byte[] en C #?


"BigEnough" array es un poco exagerado. Claro, el búfer debe ser "grande", pero el diseño adecuado de una aplicación debe incluir transacciones y delimitadores. En esta configuración, cada transacción tendrá una longitud predeterminada, por lo que su matriz anticipará cierto número de bytes y la insertará en un búfer de tamaño correcto. Los delimitadores garantizarían la integridad de la transacción y se proporcionarían dentro de cada transacción. Para mejorar aún más su aplicación, puede usar 2 canales (2 tomas). Uno comunicaría las transacciones de mensajes de control de longitud fija que incluirían información sobre el tamaño y el número de secuencia de las transacciones de datos que se transferirán utilizando el canal de datos. El receptor reconocería la creación del búfer y solo entonces se enviarían los datos. Si no tiene control sobre el emisor de la secuencia, entonces necesita un arreglo multidimensional como un búfer. Los arreglos de componentes serían lo suficientemente pequeños para ser manejables y lo suficientemente grandes para ser prácticos, según su estimación de datos esperados. La lógica de proceso buscaría delimitadores de inicio conocidos y luego terminaría con el delimitador en matrices de elementos posteriores. Una vez que se encuentra el delimitador final, se creará un nuevo búfer para almacenar datos relevantes entre delimitadores y el búfer inicial deberá reestructurarse para permitir la eliminación de los datos.

En cuanto a un código para convertir la secuencia en la matriz de bytes es uno a continuación.

Stream s = yourStream; int streamEnd = Convert.ToInt32(s.Length); byte[] buffer = new byte[streamEnd]; s.Read(buffer, 0, streamEnd);


En .NET Framework 4 y versiones posteriores, la clase Stream tiene un método CopyTo incorporado que puede usar.

Para versiones anteriores del marco, la función de ayuda práctica que debe tener es:

public static void CopyStream(Stream input, Stream output) { byte[] b = new byte[32768]; int r; while ((r = input.Read(b, 0, b.Length)) > 0) output.Write(b, 0, r); }

Luego use uno de los métodos anteriores para copiar a un MemoryStream y llame a GetBuffer en él:

var file = new FileStream("c://foo.txt", FileMode.Open); var mem = new MemoryStream(); // If using .NET 4 or later: file.CopyTo(mem); // Otherwise: CopyStream(file, mem); // getting the internal buffer (no additional copying) byte[] buffer = mem.GetBuffer(); long length = mem.Length; // the actual length of the data // (the array may be longer) // if you need the array to be exactly as long as the data byte[] truncated = mem.ToArray(); // makes another copy

Edición: originalmente sugerí usar la respuesta de Jason para una Stream que admite la propiedad Length . Pero tuvo un error porque asumió que el Stream devolvería todo su contenido en una sola Read , lo cual no es necesariamente cierto (no para un Socket , por ejemplo). No sé si hay un ejemplo de una implementación de Stream en el BCL que admite Length pero puede devolver los datos en partes más cortas de lo que solicita, pero como cualquiera puede heredar Stream este podría ser fácilmente el caso.

Es probable que para la mayoría de los casos sea más sencillo utilizar la solución general anterior, pero suponiendo que desea leer directamente en una matriz que es lo bigEnough :

byte[] b = new byte[bigEnough]; int r, offset; while ((r = input.Read(b, offset, b.Length - offset)) > 0) offset += r;

Es decir, llame repetidamente a Read y mueva la posición en la que almacenará los datos.


La solución más corta que conozco:

using(var memoryStream = new MemoryStream()) { sourceStream.CopyTo(memoryStream); return memoryStream.ToArray(); }


Llama a la siguiente función como

byte[] m_Bytes = StreamHelper.ReadToEnd (mystream);

Función:

public static byte[] ReadToEnd(System.IO.Stream stream) { long originalPosition = 0; if(stream.CanSeek) { originalPosition = stream.Position; stream.Position = 0; } try { byte[] readBuffer = new byte[4096]; int totalBytesRead = 0; int bytesRead; while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) { totalBytesRead += bytesRead; if (totalBytesRead == readBuffer.Length) { int nextByte = stream.ReadByte(); if (nextByte != -1) { byte[] temp = new byte[readBuffer.Length * 2]; Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length); Buffer.SetByte(temp, totalBytesRead, (byte)nextByte); readBuffer = temp; totalBytesRead++; } } } byte[] buffer = readBuffer; if (readBuffer.Length != totalBytesRead) { buffer = new byte[totalBytesRead]; Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead); } return buffer; } finally { if(stream.CanSeek) { stream.Position = originalPosition; } } }


Ok, tal vez me esté perdiendo algo aquí, pero esta es la forma en que lo hago:

public static Byte[] ToByteArray(this Stream stream) { Int32 length = stream.Length > Int32.MaxValue ? Int32.MaxValue : Convert.ToInt32(stream.Length); Byte[] buffer = new Byte[length]; stream.Read(buffer, 0, length); return buffer; }


Si publica un archivo desde un dispositivo móvil u otro

byte[] fileData = null; using (var binaryReader = new BinaryReader(Request.Files[0].InputStream)) { fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength); }


Técnica rápida y sucia:

static byte[] StreamToByteArray(Stream inputStream) { if (!inputStream.CanRead) { throw new ArgumentException(); } // This is optional if (inputStream.CanSeek) { inputStream.Seek(0, SeekOrigin.Begin); } byte[] output = new byte[inputStream.Length]; int bytesRead = inputStream.Read(output, 0, output.Length); Debug.Assert(bytesRead == output.Length, "Bytes read from stream matches stream length"); return output; }

Prueba:

static void Main(string[] args) { byte[] data; string path = @"C:/Windows/System32/notepad.exe"; using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read)) { data = StreamToByteArray(fs); } Debug.Assert(data.Length > 0); Debug.Assert(new FileInfo(path).Length == data.Length); }

Le preguntaría, ¿por qué quiere leer un flujo en un byte [], si desea copiar el contenido de un flujo, puedo sugerirle usar MemoryStream y escribir su flujo de entrada en un flujo de memoria?


También puede intentar leer partes por partes y expandir la matriz de bytes que se devuelve:

public byte[] StreamToByteArray(string fileName) { byte[] total_stream = new byte[0]; using (Stream input = File.Open(fileName, FileMode.Open, FileAccess.Read)) { byte[] stream_array = new byte[0]; // Setup whatever read size you want (small here for testing) byte[] buffer = new byte[32];// * 1024]; int read = 0; while ((read = input.Read(buffer, 0, buffer.Length)) > 0) { stream_array = new byte[total_stream.Length + read]; total_stream.CopyTo(stream_array, 0); Array.Copy(buffer, 0, stream_array, total_stream.Length, read); total_stream = stream_array; } } return total_stream; }


Yo uso esta clase de extensión:

public static class StreamExtensions { public static byte[] ReadAllBytes(this Stream instream) { if (instream is MemoryStream) return ((MemoryStream) instream).ToArray(); using (var memoryStream = new MemoryStream()) { instream.CopyTo(memoryStream); return memoryStream.ToArray(); } } }

Simplemente copie la clase a su solución y podrá usarla en cada flujo:

byte[] bytes = myStream.ReadAllBytes()

Funciona muy bien para todos mis flujos y guarda un montón de código! Por supuesto, puede modificar este método para usar algunos de los otros enfoques aquí para mejorar el rendimiento si es necesario, pero me gusta hacerlo simple.


byte[] buf; // byte array Stream stream=Page.Request.InputStream; //initialise new stream buf = new byte[stream.Length]; //declare arraysize stream.Read(buf, 0, buf.Length); // read from stream to byte array


Byte[] Content = new BinaryReader(file.InputStream).ReadBytes(file.ContentLength);


Stream s; int len = (int)s.Length; byte[] b = new byte[len]; int pos = 0; while((r = s.Read(b, pos, len - pos)) > 0) { pos += r; }

Una solución un poco más complicada es necesaria si la s.Length excede Int32.MaxValue . Pero si necesita leer un flujo tan grande en la memoria, puede pensar en un enfoque diferente para su problema.

Editar: si su transmisión no admite la propiedad Length , modifíquela utilizando la workaround de Earwicker.

public static class StreamExtensions { // Credit to Earwicker public static void CopyStream(this Stream input, Stream output) { byte[] b = new byte[32768]; int r; while ((r = input.Read(b, 0, b.Length)) > 0) { output.Write(b, 0, r); } } } [...] Stream s; MemoryStream ms = new MemoryStream(); s.CopyStream(ms); byte[] b = ms.GetBuffer();