2010-01-22 40 views
5

Benim çalışma yerimde bir ASP.net sitesinde, aşağıdaki dosya kodu dosya indirme işlemlerini yürütmekten sorumludur (NOT: Response.TransmitFile, içeriğin indirilmesinden dolayı burada kullanılmaz.) bir zip dosyası akışı yapılan:ASP.net kullanım sırasında bellek kullanımı

private void DownloadFile(Stream stream) 
{ 
     int bytesRead; 
     int chunkSize = 1048576; //1MB 

     byte[] readBuffer = new byte[chunkSize]; 
     while ((bytesRead = stream.Read(readBuffer, 0, readBuffer.Length)) != 0) 
      { 
       if(!Response.IsClientConnected) 
        break; 
       byte[] chunk = new byte[bytesRead]; 
       Array.Copy(readBuffer,0,chunk,0,bytesRead); 
       Response.BinaryWrite(chunk); 
       Response.Flush(); 
     } 
     stream.Close(); 
} 

Kullanıcılarımız sık oldukça hızlı sunucu belleği çiğnemek multi-yüz MB dosyalarını indirmek. Benim varsayımım bunun yanıt tamponlaması nedeniyle olmasıdır. bu mantıklı mı?

Sadece Response nesnesinin 'buffer' özelliği hakkında okudum. Bunu false olarak ayarlarsanız, Response.BinaryWrite() çağrıları bellekteki verileri arabelleğe almayı engeller mi? Genel olarak, bu durumda bellek kullanımını sınırlamak için iyi bir yol nedir? Belki de posta dosyasından geçici bir dosyaya akışı yapmalıyım, sonra Response.TransmitFile()?

DÜZENLEME: Olası çözümlere ek olarak, yukarıdaki kodda bulunan bellek kullanımı sorununu açıklamak istiyorum. Neden her döngü yineleme üzerinde Response.Flush çağrılsa bile, bu neden 1MB'den daha fazla tüketir? Her döngü yinelemesinde (ve hemen GC'leri almaz) ortaya çıkan gereksiz yığın ayırma mı yoksa işte başka bir şey mi var?

cevap

4

Bunun için üzerinde çalıştığım bazı kodlar. Dosyayı parçalar halinde göndermek için 8000 baytlık bir arabellek kullanır. Büyük bir dosyadaki bazı gayri resmi testler, tahsis edilen bellekte önemli bir düşüş göstermiştir.

int BufferSize = 8000; 
FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); 
try { 
    long fileSize = stream.Length; 

    long dataLeftToRead = fileSize; 
    int chunkLength; 
    buffer = new Byte[BufferSize]; 

    while (dataLeftToRead > 0) { 
    if (!Response.IsClientConnected) { 
     break; 
    } 
    chunkLength = stream.Read(buffer, 0, BufferSize); 

    Response.OutputStream.Write(buffer, 0, chunkLength); 
    Response.Flush(); 

    dataLeftToRead -= chunkLength; 
    } 
} 
finally { 
    if (stream != null) { 
    stream.Close(); 
} 

bir sözdizim hatası ve eksik değeri

+0

bilgiçlik taslayan Yorum düzeltmek için düzenlendi: 8k = 8192 byte; –

+0

thanx - sabit - biz geeks özenle doğru olmalı – Ray

+2

Response.Write kullanarak doğrudan Response.OutputStream nesnesine yazmak arasındaki fark nedir? – Odrade