txt - C#guardar un archivo desde una solicitud HTTP
openfiledialog guardar archivo (3)
Estoy tratando de descargar y guardar un archivo de un HttpWebResponse pero tengo problemas para guardar el archivo correctamente (aparte de los archivos de texto).
Creo que es algo que ver con esta parte:
byte[] byteArray = Encoding.UTF8.GetBytes(http.Response.Content);
MemoryStream stream = new MemoryStream(byteArray);
Los archivos de texto funcionan bien con el código anterior, pero cuando intento guardar el contenido en un archivo de imagen, se corrompe. ¿Cómo escribo estos datos de ''cadena'' en un archivo de imagen (y otros archivos binarios)
Olvidé mencionar, Este es .NET CP 3.5 y tengo una clase de envoltorio alrededor de la clase HttpWebResponse para agregar OAuth, etc.
El problema es que interpretas los datos binarios como texto, incluso si no lo es, tan pronto como comienzas a tratar el contenido como una cadena en lugar de bytes, estás en problemas. No ha proporcionado los detalles de su clase contenedora, pero supongo que su propiedad Content
está devolviendo una cadena, no podrá usarla. Si su clase contenedora no le permite obtener los datos en bruto de la respuesta web, deberá modificarlos.
Si está utilizando .NET 4, puede usar el nuevo método CopyTo:
using (Stream output = File.OpenWrite("file.dat"))
using (Stream input = http.Response.GetResponseStream())
{
input.CopyTo(output);
}
Si no está utilizando .NET 4, tiene que hacer la copia manualmente:
using (Stream output = File.OpenWrite("file.dat"))
using (Stream input = http.Response.GetResponseStream())
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
La forma más simple que encontré es:
- Utilice ReadAsByteArrayAsync para obtener los datos.
- Enumere el elemento File.WriteAllBytes para guardar el archivo.
No hay necesidad de recorrer nada. Ejemplo en contexto a continuación:
[TestClass]
public class HttpTests
{
[TestMethod]
public void TestMethod1()
{
var jsObject = (dynamic)new JObject();
jsObject.html = "samplehtml.html";
jsObject.format = "jpeg";
const string url = "https://mywebservice.com/api";
var result = GetResponse(url, jsObject).GetAwaiter().GetResult();
File.WriteAllBytes($@"c:/temp/httpresult.{jsObject.format}", result);
}
static async Task<byte[]> GetResponse(string uri, dynamic jsObj)
{
var httpClient = new HttpClient();
var load = jsObj.ToString();
var content = new StringContent(load, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(uri, content);
return await response.Content.ReadAsByteArrayAsync();
}
}
Utilice WebClient.DownloadFile . Puede hacerlo manualmente (algo como esto ), pero WebClient es la mejor opción para descargas simples.