OutOfMemoryException当发送大文件500MB使用FileStream ASPNET [英] OutOfMemoryException when send big file 500MB using FileStream ASPNET
问题描述
我使用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)
{
//如果我们被传递了一个无效的初始长度,只需
//使用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(read == buffer.Length)
{
int nextByte = stream.ReadByte();
//结束流?如果是这样,我们完成
if(nextByte == -1)
{
return buffer;
}
//不,调整缓冲区大小,放入我们刚刚
//读取的字节,然后继续
byte [] newBuffer = new byte [buffer.Length * 2];
Array.Copy(buffer,newBuffer,buffer.Length);
newBuffer [read] =(byte)nextByte;
buffer = newBuffer;
read ++;
}
}
//缓冲区现在太大了。收缩它
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 ...
如果比Stream更好的BufferedStream(FileStream,MemoryStream,...)?
使用BufferedStream,可以读取700 MB的大文件吗? (任何示例代码源使用BufferedStream下载大文件)
我想,这是一个问题:不是如何读取500mb文件到内存?但是,如何发送一个大文件到ASPNET响应流?
我发现这个代码由Cheeso:
使用(var fs = new FileStream(filePath,FileMode.Open,FileAccess.Read))
{
Response.BufferOutput = false;
//以防止缓冲
byte [] buffer = new byte [1024];
int bytesRead = 0;
while((bytesRead = fs.Read(buffer,0,buffer.Length))> 0)
{
Response.OutputStream.Write(buffer,0,bytesRead);
}
}
是不是很好的代码?任何对高性能的改进?
一个collegue说我,使用
Response.TransmitFile(文件路径);
现在,另一个问题,更好的TransmitFile或Cheeso代码?
许多年以前,在msdn杂志上看到很好的文章,但是我无法访问 http://msdn.microsoft.com/msdnmag/issues/06/09/WebDownloads/ ,
更新:您可以使用链接中的 webarchive 访问: https://web.archive.org/web/20070627063111/http://msdn.microsoft.com/msdnmag/issues/06/09/ WebDownloads /
任何建议,评论,示例代码来源??
我创建了下载页面,允许用户在几个月前下载最多4gb(可能更多)。这是我的工作片段:
private void TransmitFile(string fullPath,string outFileName)
{
系统.IO.Stream iStream = null;
//块读取10K字节的缓冲区:
byte [] buffer = new Byte [10000];
//文件长度:
int length;
//要读取的字节总数:
long dataToRead;
//识别要下载的文件,包括其路径。
string filepath = fullPath;
//识别文件名。
string filename = System.IO.Path.GetFileName(filepath);
try
{
//打开文件。
iStream = new System.IO.FileStream(filepath,System.IO.FileMode.Open,
System.IO.FileAccess.Read,System.IO.FileShare.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());
//读取字节。
while(dataToRead> 0)
{
//验证客户端是否连接。
if(Response.IsClientConnected)
{
//读取缓冲区中的数据。
length = iStream.Read(buffer,0,10000);
//将数据写入当前输出流。
Response.OutputStream.Write(buffer,0,length);
//将数据刷新到输出。
Response.Flush();
buffer = new Byte [10000];
dataToRead = dataToRead - length;
}
else
{
//防止无限循环,如果用户断开
dataToRead = -1;
}
}
}
catch(Exception ex)
{
抛出新的ApplicationException(ex.Message);
}
finally
{
if(iStream!= null)
{
//关闭文件。
iStream.Close();
}
Response.Close();
}
}
I'm using Filestream for read big file (> 500 MB) and I get the OutOfMemoryException.
I use Asp.net , .net 3.5, win2003, iis 6.0
I want this in my app:
Read DATA from Oracle
Uncompress file using FileStream and BZip2
Read file uncompressed and send it to asp.net page for download.
When I read file from disk, Fails !!! and get OutOfMemory...
. My Code is:
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;
}
Now, I specify my issue better.
Uncompress file using FileStream and BZip2 is OK, all is right.
The Problem is the following:
Read fat big file in disk (> 500 MB) in byte[] and send bytes to Response (asp.net) for download it.
When use
http://www.yoda.arachsys.com/csharp/readbinary.html
public static byte[] ReadFully
I get the error: OutOfMemoryException...
If better BufferedStream than Stream (FileStream, MemoryStream, ...) ??
Using BufferedStream , Can I read big file of 700 MB ?? (any sample code source using BufferedStream for download big file)
I think, this is the question: Not "how to read a 500mb file into memory?" , But "how to send a large file to the ASPNET Response stream?"
I found this code by 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);
}
}
Is it good code ?? any improvements for high performance ??
A collegue say me, use
Response.TransmitFile(filePath);
Now, another question, better TransmitFile or code by Cheeso ??
Many years ago, in msdn magazine appears great article about it but I cannot access http://msdn.microsoft.com/msdnmag/issues/06/09/WebDownloads/,
Update: You can access using webarchive in the link: https://web.archive.org/web/20070627063111/http://msdn.microsoft.com/msdnmag/issues/06/09/WebDownloads/
Any suggestions, comments, sample code source??
I've created download page which allows user to download up to 4gb (may be more) few months ago. Here is my working snippet:
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();
}
}
这篇关于OutOfMemoryException当发送大文件500MB使用FileStream ASPNET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!