tamaño saber obtener fecha esta ejemplo detalles creacion como archivo abierto c# filestream

saber - obtener el tamaño de un archivo en c#



Devolver una secuencia desde File.OpenRead() (5)

Estoy en el proceso de escribir un servicio de WCF que permitirá que un sitio web ASP.Net recupere archivos (en base a este artículo ). Mi problema es que cuando devuelvo la transmisión, está en blanco.

Para simplificar, he aislado el código en una aplicación simple de winforms para tratar de encontrar cuál es el problema al devolver una transmisión y este es el código:

private Stream TestStream() { Stream fs = File.OpenRead(@"c:/testdocument.docx"); return fs; } // This method converts the filestream into a byte array so that when it is // used in my ASP.Net project the file can be sent using response.Write private void Test() { System.IO.MemoryStream data = new System.IO.MemoryStream(); System.IO.Stream str = TestStream(); str.CopyTo(data); byte[] buf = new byte[data.Length]; data.Read(buf, 0, buf.Length); }

El resultado de este código es que buf tiene una longitud de 12.587 bytes (la longitud correcta del archivo) pero solo contiene 0.

El documento de Word se abre sin problemas si lo intento, ¿me falta algo obvio?


Intenta cambiar tu código a esto:

private void Test() { System.IO.MemoryStream data = new System.IO.MemoryStream(TestStream()); byte[] buf = new byte[data.Length]; data.Read(buf, 0, buf.Length); }


Necesitas

str.CopyTo(data); data.Position = 0; // reset to beginning byte[] buf = new byte[data.Length]; data.Read(buf, 0, buf.Length);

Y dado que su método Test() imita al cliente, debe Close() o Dispose() el str Stream. Y el memoryStream también, solo fuera del principal.


Olvidó restablecer la posición de la secuencia de la memoria:

private void Test() { System.IO.MemoryStream data = new System.IO.MemoryStream(); System.IO.Stream str = TestStream(); str.CopyTo(data); // Reset memory stream data.Seek(0, SeekOrigin.Begin); byte[] buf = new byte[data.Length]; data.Read(buf, 0, buf.Length); }

Actualizar:

Hay una cosa más a tener en cuenta: generalmente vale la pena no ignorar los valores de retorno de los métodos. Una implementación más robusta debería verificar cuántos bytes se han leído después de que la llamada retorna:

private void Test() { using(MemoryStream data = new MemoryStream()) { using(Stream str = TestStream()) { str.CopyTo(data); } // Reset memory stream data.Seek(0, SeekOrigin.Begin); byte[] buf = new byte[data.Length]; int bytesRead = data.Read(buf, 0, buf.Length); Debug.Assert(bytesRead == data.Length, String.Format("Expected to read {0} bytes, but read {1}.", data.Length, bytesRead)); } }


Olvidaste buscar:

str.CopyTo(data); data.Seek(0, SeekOrigin.Begin); // <-- missing line byte[] buf = new byte[data.Length]; data.Read(buf, 0, buf.Length);


Opciones:

  • Usa data.Seek como lo sugiere ken2k
  • Use la propiedad Position algo más simple:

    data.Position = 0;

  • Use la llamada ToArray en MemoryStream para que su vida sea más simple para empezar:

    byte[] buf = data.ToArray();

La tercera opción sería mi enfoque preferido.

Tenga en cuenta que debe tener una instrucción using para cerrar la secuencia de archivos automáticamente (y opcionalmente para MemoryStream ), y agregaría una directiva using para System.IO para que su código sea más limpio:

byte[] buf; using (MemoryStream data = new MemoryStream()) { using (Stream file = TestStream()) { file.CopyTo(data); buf = data.ToArray(); } } // Use buf

Es posible que también desee crear un método de extensión en Stream para hacer esto por usted en un solo lugar, por ejemplo

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

Tenga en cuenta que esto no cierra la secuencia de entrada.