我正在使用Filestream读取大文件(> 500 MB),并且收到OutOfMemoryException。
我使用Asp.net,.net 3.5,win2003,iis 6.0
我想要在我的应用程序中使用这个:]
从Oracle读取数据
使用FileStream和BZip2解压缩文件
读取未压缩的文件,并将其发送到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解压缩文件就可以了,没事。
问题如下:
以字节[]读取磁盘中的大文件(> 500 MB),然后将字节发送到Response(asp.net)进行下载。
使用时
http://www.yoda.arachsys.com/csharp/readbinary.html
public static byte[] ReadFully
我收到错误:OutOfMemoryException ...
如果BufferedStream比Stream(FileStream,MemoryStream,...)更好?
使用BufferedStream,我可以读取700 MB的大文件吗? (使用BufferedStream下载大文件的任何示例代码源)
我认为,这是一个问题:不是“如何将500mb文件读入内存?” ,但是“如何将大文件发送到ASPNET Response流?”
我由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);
}
}
是好的代码吗?对高性能的任何改进?
一个同事说我,使用
Response.TransmitFile(filePath);
现在,另一个问题,更好的TransmitFile或Cheeso的代码??
很多年前,在《 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进行访问。任何建议,评论,示例代码源?
我正在使用Filestream读取大文件(> 500 MB),并且收到OutOfMemoryException。我使用Asp.net,.net 3.5,win2003,iis 6.0在我的应用程序中需要这样做:使用...
<<<我已经创建了下载页面,该页面允许用户在几个月前下载高达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();
}
}
您不需要将整个文件保存在内存中,只需读取它并循环写入响应流。
1-使用RecyclableMemoryStream代替MemoryStream解决方案
/// <summary>Based upon https://stackoverflow.com/a/3363015/595473 </summary>
public class BufferedFileStreamResult : System.Web.Mvc.FileStreamResult
{
public BufferedFileStreamResult(System.IO.Stream stream, string contentType, string fileDownloadName)
: base(stream, contentType)
{
FileDownloadName = fileDownloadName;
}
public int BufferSize { get; set; } = 16 * 1024 * 1024;//--16MiB
protected override void WriteFile(System.Web.HttpResponseBase response)
{
try
{
response.Clear();
response.AddHeader("Content-Disposition", $"attachment; filename={FileDownloadName}");
response.AddHeader("Content-Length", FileStream.Length.ToString());
byte[] buffer;
int bytesRead;
while (response.IsClientConnected)//--Prevent infinite loop if user disconnects
{
buffer = new byte[BufferSize];
//--Read the data in buffer
if ((bytesRead = FileStream.Read(buffer, 0, BufferSize)) == 0)
{
break;//--Stop writing if there's nothing left to write
}
//--Write the data to the current output stream
response.OutputStream.Write(buffer, 0, bytesRead);
//--Flush the data to the output
response.Flush();
}
}
finally
{
FileStream?.Close();
response.Close();
}
}
}