2017-01-03 8 views
0

Я хочу загрузить файл с помощью http post. Следующий метод работает хорошо, но с файлами> 1GB я получаю OutOfMemoryExceptionsOutOfMemoryException при загрузке файла с помощью System.Net.WebClient

Я нашел solutions основанный на AllowWriteStreamBuffering и System.Net.WebRequest, но это не похоже, помогает быть в этом случае, потому что мне нужно решить эту проблему с System.Net.WebClient.

Использование памяти моего приложения, когда исключение всегда о ~ 500MB

string file = @"C:\test.zip"; 
string url = @"http://foo.bar"; 
using (System.Net.WebClient client = new System.Net.WebClient()) 
{ 
    using (System.IO.Stream fileStream = System.IO.File.OpenRead(file)) 
    { 
     using (System.IO.Stream requestStream = client.OpenWrite(new Uri(url), "POST")) 
     { 
      byte[] buffer = new byte[16 * 1024]; 
      int bytesRead; 
      while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       requestStream.Write(buffer, 0, bytesRead); 
      } 
     } 
    } 
} 

Что мне нужно изменить, чтобы избежать этой ошибки?

+0

Рассматривали ли вы с помощью [WebClient.UploadFileAsync] (https://msdn.microsoft.com/en-us /library/ms144232(v=vs.110).aspx)? –

+0

Вопросы, подобные этим, должны документировать установленный продукт для защиты от вредоносных программ. И показать трассировку стека с включенной неуправляемой отладкой. –

ответ

1

После 1 дня попытки я нашел решение этой проблемы.

Может быть, это поможет некоторым будущим посетителям

string file = @"C:\test.zip"; 
string url = @"http://foo.bar"; 
using (System.IO.Stream fileStream = System.IO.File.OpenRead(file)) 
{ 
    using (ExtendedWebClient client = new ExtendedWebClient(fileStream.Length)) 
    { 
     using (System.IO.Stream requestStream = client.OpenWrite(new Uri(url), "POST")) 
     { 
      byte[] buffer = new byte[16 * 1024]; 
      int bytesRead; 
      while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       requestStream.Write(buffer, 0, bytesRead); 
      } 
     } 
    } 
} 

Расширенная WebClient метод

private class ExtendedWebClient : System.Net.WebClient 
{ 
    public long ContentLength { get; set; } 
    public ExtendedWebClient(long contentLength) 
    { 
     ContentLength = contentLength; 
    } 

    protected override System.Net.WebRequest GetWebRequest(Uri uri) 
    { 
     System.Net.HttpWebRequest hwr = (System.Net.HttpWebRequest)base.GetWebRequest(uri); 
     hwr.AllowWriteStreamBuffering = false; //do not load the whole file into RAM 
     hwr.ContentLength = ContentLength; 
     return (System.Net.WebRequest)hwr; 
    } 
} 
Смежные вопросы