2012-04-18 4 views
0

Я реализую простой инструмент для загрузки файлов с помощью RestSharp. Когда я добавляю большой файл в запрос с помощью создателя собственного потока (для обновления процесса загрузки в gui), stream.Write генерирует исключение OutOfMemoryException. Пример с упрощенным кодом:OutOfMemoryException с загрузкой файла RestSharp

... 
var request = new RestRequest { Resource = "/test" }; 
request.Method = Method.POST; 
request.AddFile("file", writer, "largefile.iso"); 

var response = client.Execute(request); 
... 

private void writer(Stream stream) 
{ 
    using (FileStream reader = File.OpenRead("d:\\download\\largefile.iso")) 
    { 
     byte[] buffer = new byte[16384]; //16k buffer 
     int bytesRead = 0; 
     int read = 0; 

     while ((read = reader.Read(buffer, 0, buffer.Length)) > 0) 
     { 
     stream.Write(buffer, 0, read); 
     bytesRead += read; 
     System.Diagnostics.Debug.WriteLine("uploading: " + (int) ((double)bytesRead/reader.Length * 100) + "%"); 
     } 
     reader.Close(); 
    } 

} 

Это прекрасно работает с небольшими файлами, но Stream пишет утечки памяти, в конечном итоге сбой. Есть что-то, чего я здесь не хватает?

+0

В .net есть предел памяти. для 32-битной системы, я думаю, что это что-то вроде 2gb. Если ваш файл превышает этот предел памяти, генерируется исключение OutOfMemory. Вы можете попытаться разбить файл на более мелкие куски и снова объединить их. – daryal

+0

Пара примечаний стороны: 1) Если вы используете .NET 4, вы должны использовать ['Stream.CopyTo'] (http://msdn.microsoft.com/en-us/library/dd782932.aspx) вместо сворачивая свою собственную версию. 2) Я почти уверен, что «читатель» будет закрыт для вас, когда он будет использован вашим «использованием», поэтому вам не нужно будет это объяснять. –

+0

Причина, по которой я использую это, - это то, что я хочу сообщать о прогрессе от фонового работника в gui. Это сделано вместо этого отладки в примере. – kohni

ответ

0

Может быть, вы должны попытаться очистить буфер потока после каждой операции записи:

private void writer(Stream stream) 
    { 
     using (FileStream reader = File.OpenRead("d:\\download\\largefile.iso")) 
     { 
      byte[] buffer = new byte[16384]; //16k buffer 
      int bytesRead = 0; 
      int read = 0; 

      while ((read = reader.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       stream.Write(buffer, 0, read); 
       stream.Flush(); 
       bytesRead += read; 
       System.Diagnostics.Debug.WriteLine("uploading: " + (int)((double)bytesRead/reader.Length * 100) + "%"); 
      } 
      reader.Close(); 
     } 

    } 
+0

Спасибо за ваш ответ. Промывка потока не помогла. Пробовал это уже ... Как я уже сказал, пример отлично работает, пока файлize kohni