2008-10-07 13 views
9

¿Cuál es la mejor manera de obtener un archivo (en este caso, un archivo .PDF, pero cualquier archivo lo hará) desde un WebResponse y ponerlo en un MemoryStream? El uso de .GetResponseStream() de WebResponse obtiene un objeto Stream, pero si desea convertir esa transmisión a un tipo específico de transmisión, ¿qué hace?¿Cómo coloco un WebResponse en una secuencia de memoria?

Respuesta

0

Copié esto de la web hace aproximadamente un año.

//---------- Start HttpResponse 
if(objHttpWebResponse.StatusCode == HttpStatusCode.OK) 
    { 
     //Get response stream 
     objResponseStream = objHttpWebResponse.GetResponseStream(); 

     //Load response stream into XMLReader 
     objXMLReader = new XmlTextReader(objResponseStream); 

     //Declare XMLDocument 
     XmlDocument xmldoc = new XmlDocument(); 
     xmldoc.Load(objXMLReader); 

     //Set XMLResponse object returned from XMLReader 
     XMLResponse = xmldoc; 

     //Close XMLReader 
     objXMLReader.Close(); 
    } 

    //Close HttpWebResponse 
    objHttpWebResponse.Close(); 
} 
+0

esto no muestra cómo poner una WebResponse en un MemoryStream como el cartel original solicitado. –

-3

He encontrado lo siguiente en http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/eeeefd81-8800-41b2-be63-71acdaddce0e/

Dim request As WebRequest 
    Dim response As WebResponse = Nothing 
    Dim s As Stream = Nothing 
    Dim fs As FileStream = Nothing 
    Dim file As MemoryStream = Nothing 

    Dim uri As New Uri(String.Format("http://forums.microsoft.com/forums/ShowPost.aspx?PostID=2992978&SiteID=1")) 
    request = WebRequest.Create(uri) 
    request.Timeout = 10000 
    response = request.GetResponse 
    s = response.GetResponseStream 

    '2 - Receive file as memorystream 
    Dim read(256) As Byte 
    Dim count As Int32 = s.Read(read, 0, read.Length) 
    File = New MemoryStream 
    Do While (count > 0) 
     File.Write(read, 0, count) 
     count = s.Read(read, 0, read.Length) 
    Loop 
    File.Position = 0 
    'Close responsestream 
    s.Close() 
    response.Close() 

    '3 - Save file 
    fs = New FileStream("c:\test.html", FileMode.CreateNew) 
    count = file.Read(read, 0, read.Length) 
    Do While (count > 0) 
     fs.Write(read, 0, count) 
     count = file.Read(read, 0, read.Length) 
    Loop 
    fs.Close() 
    File.Close() 
+2

Este es un código muy descuidado, ¡nunca usaría eso! – emalamisura

25

Hay un problema serio con SoloBold de answer que he descubierto durante las pruebas de ello. Al usarlo para leer un archivo a través de FtpWebRequest en un MemoryStream, no se pudo leer intermitentemente todo el flujo en la memoria. Seguí esto hasta Peek(), algunas veces devolviendo -1 después de los primeros 1460 bytes, aunque hubiera tenido éxito un Read() (el archivo era significativamente más grande que este).

En cambio, propongo la solución a continuación:

MemoryStream memStream; 
using (Stream response = request.GetResponseStream()) { 
    memStream = new MemoryStream(); 

    byte[] buffer = new byte[1024]; 
    int byteCount; 
    do { 
     byteCount = stream.Read(buffer, 0, buffer.Length); 
     memStream.Write(buffer, 0, byteCount); 
    } while (byteCount > 0); 
} 

// If you're going to be reading from the stream afterwords you're going to want to seek back to the beginning. 
memStream.Seek(0, SeekOrigin.Begin); 

// Use memStream as required 
+0

Esto funciona para mí, mientras que las otras respuestas no funcionaron. – Matt

+1

Gracias por la respuesta, Lawrence. Obtuve resultados inconsistentes intentando hacer esto de otras maneras. – Cashley

+1

Cuando observa el IL generado (a través de dotPeek) por el método CopyTo (Stream, Int32) en .NET 4.0 notará que genera código con el mismo patrón pero usando una sola línea de código. https://msdn.microsoft.com/en-us/library/system.io.stream.copyto(v=vs.100).aspx. response.CopytTo (memStream, 1024); memStream.Position = 0; –

Cuestiones relacionadas