2010-07-29 4 views
9

큰 파일 (> 500MB)을 읽으려면 Filestream을 사용하고 OutOfMemoryException을받습니다. OutOfMemoryException FileStream을 사용하여 큰 파일을 500MB 전송 ASPNET

압축 해제 파일을 사용하여 FileStream 및 BZip2로

오라클

에서

읽기 자료 :

내가 Asp.net를 사용하여 .NET 3.5, WIN2003은 6.0

내가 내 응용 프로그램이 원하는 IIS를

파일을 압축 해제하고 asp.net 페이지로 다운로드하여 다운로드하십시오.

디스크에서 파일을 읽을 때 실패 함 !!! OutOfMemory ...

. 내 코드 :

using (var fs3 = new FileStream(filePath2, FileMode.Open, FileAccess.Read)) 
     { 
      byte[] b2 = ReadFully(fs3, 1024); 
     } 

// http://www.yoda.arachsys.com/csharp/readbinary.html 
public static byte[] ReadFully(Stream stream, int initialLength) 
    { 
    // If we've been passed an unhelpful initial length, just 
    // use 32K. 
    if (initialLength < 1) 
    { 
     initialLength = 32768; 
    } 

    byte[] buffer = new byte[initialLength]; 
    int read = 0; 

    int chunk; 
    while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0) 
    { 
     read += chunk; 

     // If we've reached the end of our buffer, check to see if there's 
     // any more information 
     if (read == buffer.Length) 
     { 
     int nextByte = stream.ReadByte(); 

     // End of stream? If so, we're done 
     if (nextByte == -1) 
     { 
      return buffer; 
     } 

     // Nope. Resize the buffer, put in the byte we've just 
     // read, and continue 
     byte[] newBuffer = new byte[buffer.Length * 2]; 
     Array.Copy(buffer, newBuffer, buffer.Length); 
     newBuffer[read] = (byte)nextByte; 
     buffer = newBuffer; 
     read++; 
     } 
    } 
    // Buffer is now too big. Shrink it. 
    byte[] ret = new byte[read]; 
    Array.Copy(buffer, ret, read); 
    return ret; 
    } 

이제 문제를 자세히 설명합니다.

FileStream 및 BZip2를 사용하는 파일 압축 해제는 모두 정상입니다.

은 [] 바이트의 디스크에 (> 500MB의) 지방이 큰 파일을 읽고 다운로드 그것에 대한 응답 (asp.net) 바이트를 보내

문제는이 다음이다.

사용

http://www.yoda.arachsys.com/csharp/readbinary.html

public static byte[] ReadFully 

내가 오류 얻을 :에서 OutOfMemoryException을 ...

하면 더 나은 한 BufferedStream보다 더 스트림 (하여 FileStream, MemoryStream을, ...)?

BufferedStream을 사용하면 700MB의 큰 파일을 읽을 수 있습니까 ?? (큰 파일을 다운로드하기 위해 BufferedStream을 사용하는 모든 샘플 코드 소스)

"이것은 500MB 파일을 메모리로 읽는 방법"이 아니라고 생각합니다. ,하지만 "큰 파일을 ASPNET 응답 스트림으로 보내는 방법은 무엇입니까?"

나는 Cheeso하여이 코드를 발견 : 그것은 좋은 코드

using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 
{ 
    Response.BufferOutput= false; // to prevent buffering 
    byte[] buffer = new byte[1024]; 
    int bytesRead = 0; 
    while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     Response.OutputStream.Write(buffer, 0, bytesRead); 
    } 
} 

인가를? 고성능을위한 모든 개선 ??

의 동료

날, 이제 또 다른 질문, Cheeso하여 더 나은 전송 작업 또는 코드를

Response.TransmitFile(filePath); 

을 사용하는 말?

많은 년 전, MSDN에서 잡지는 그것에 대해 좋은 기사를 표시하지만 http://msdn.microsoft.com/msdnmag/issues/06/09/WebDownloads/,

업데이트에 액세스 할 수 없습니다 : https://web.archive.org/web/20070627063111/http://msdn.microsoft.com/msdnmag/issues/06/09/WebDownloads/

어떤 제안, 의견 : 당신은 링크 webarchive를 사용하여 액세스 할 수 , 샘플 코드 소스 ??

답변

16

몇 달 전에 최대 4GB까지 다운로드 할 수있는 다운로드 페이지를 만들었습니다. 제 작업 스 니펫은 다음과 같습니다.

private void TransmitFile(string fullPath, string outFileName) 
    { 
     System.IO.Stream iStream = null; 

     // Buffer to read 10K bytes in chunk: 
     byte[] buffer = new Byte[10000]; 

     // Length of the file: 
     int length; 

     // Total bytes to read: 
     long dataToRead; 

     // Identify the file to download including its path. 
     string filepath = fullPath; 

     // Identify the file name. 
     string filename = System.IO.Path.GetFileName(filepath); 

     try 
     { 
      // Open the file. 
      iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, 
         System.IO.FileAccess.Read, System.IO.FileShare.Read); 


      // Total bytes to read: 
      dataToRead = iStream.Length; 

      Response.Clear(); 
      Response.ContentType = "application/octet-stream"; 
      Response.AddHeader("Content-Disposition", "attachment; filename=" + outFileName); 
      Response.AddHeader("Content-Length", iStream.Length.ToString()); 

      // Read the bytes. 
      while (dataToRead > 0) 
      { 
       // Verify that the client is connected. 
       if (Response.IsClientConnected) 
       { 
        // Read the data in buffer. 
        length = iStream.Read(buffer, 0, 10000); 

        // Write the data to the current output stream. 
        Response.OutputStream.Write(buffer, 0, length); 

        // Flush the data to the output. 
        Response.Flush(); 

        buffer = new Byte[10000]; 
        dataToRead = dataToRead - length; 
       } 
       else 
       { 
        //prevent infinite loop if user disconnects 
        dataToRead = -1; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new ApplicationException(ex.Message); 
     } 
     finally 
     { 
      if (iStream != null) 
      { 
       //Close the file. 
       iStream.Close(); 
      } 
      Response.Close(); 
     } 
    } 
2

전체 파일을 읽고 단지 루프로 응답 스트림에 쓸 필요는 없습니다.

관련 문제