C# 使用HttpWebRequest传输大文件时出现内存不足异常
当使用Http.Put处理大文件时,我遇到内存不足异常。我使用的是一个异步模型,如代码所示。我正在尝试向Windows 2008 R2服务器发送8K数据块。当我尝试写入超过5368864字节的数据块时,异常始终发生。以下代码段中的requestStream.Write方法发生异常 寻找原因为什么 注意:较小的文件可以放入。如果我写入本地文件流,逻辑也可以工作。在Win 7 Ultimate客户端计算机上运行VS 2010、.Net 4.0C# 使用HttpWebRequest传输大文件时出现内存不足异常,c#,streaming,out-of-memory,C#,Streaming,Out Of Memory,当使用Http.Put处理大文件时,我遇到内存不足异常。我使用的是一个异步模型,如代码所示。我正在尝试向Windows 2008 R2服务器发送8K数据块。当我尝试写入超过5368864字节的数据块时,异常始终发生。以下代码段中的requestStream.Write方法发生异常 寻找原因为什么 注意:较小的文件可以放入。如果我写入本地文件流,逻辑也可以工作。在Win 7 Ultimate客户端计算机上运行VS 2010、.Net 4.0 HttpWebRequest request =
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("Http://website/FileServer/filename");
request.Method = WebRequestMethods.Http.Put;
request.SendChunked = true;
request.AllowWriteStreamBuffering = true;
...
request.BeginGetRequestStream( new AsyncCallback(EndGetStreamCallback), state);
...
int chunk = 8192; // other values give same result
....
private static void EndGetStreamCallback(IAsyncResult ar) {
long limit = 0;
long fileLength;
HttpState state = (HttpState)ar.AsyncState;
Stream requestStream = null;
// End the asynchronous call to get the request stream.
try {
requestStream = state.Request.EndGetRequestStream(ar);
// Copy the file contents to the request stream.
FileStream stream = new FileStream(state.FileName, FileMode.Open, FileAccess.Read, FileShare.None, chunk, FileOptions.SequentialScan);
BinaryReader binReader = new BinaryReader(stream);
fileLength = stream.Length;
// Set Position to the beginning of the stream.
binReader.BaseStream.Position = 0;
byte[] fileContents = new byte[chunk];
// Read File from Buffer
while (limit < fileLength)
{
fileContents = binReader.ReadBytes(chunk);
// the next 2 lines attempt to write to network and server
requestStream.Write(fileContents, 0, chunk); // causes Out of memory after 536,868,864 bytes
requestStream.Flush(); // I get same result with or without Flush
limit += chunk;
}
// IMPORTANT: Close the request stream before sending the request.
stream.Close();
requestStream.Close();
}
}
HttpWebRequest request=(HttpWebRequest)WebRequest.Create(“Http://website/FileServer/filename");
request.Method=WebRequestMethods.Http.Put;
request.SendChunked=true;
request.AllowWriteStreamBuffering=true;
...
BeginGetRequestStream(新的AsyncCallback(EndGetStreamCallback),state);
...
int chunk=8192;//其他值给出相同的结果
....
私有静态void EndGetStreamCallback(IAsyncResult ar){
长限=0;
长文件长度;
HttpState=(HttpState)ar.AsyncState;
Stream requestStream=null;
//结束异步调用以获取请求流。
试一试{
requestStream=state.Request.EndGetRequestStream(ar);
//将文件内容复制到请求流。
FileStream stream=新FileStream(state.FileName、FileMode.Open、FileAccess.Read、FileShare.None、chunk、FileOptions.SequentialScan);
BinaryReader=新的BinaryReader(流);
fileLength=stream.Length;
//将位置设置为流的开头。
binReader.BaseStream.Position=0;
字节[]文件内容=新字节[块];
//从缓冲区读取文件
while(限制<文件长度)
{
fileContents=binReader.ReadBytes(块);
//接下来的两行尝试写入网络和服务器
Write(fileContents,0,chunk);//导致5368864字节后内存不足
requestStream.Flush();//无论是否使用Flush,我都会得到相同的结果
限制+=块;
}
//重要提示:在发送请求之前关闭请求流。
stream.Close();
requestStream.Close();
}
}
你显然有。当AllowWriteStreamBuffering
为true
时,它会缓冲写入请求的所有数据!因此,“解决方案”是将该属性设置为false
:
要解决此问题,请将HttpWebRequest.AllowWriteStreamBuffering属性设置为false
POST也会发生同样的情况吗?您的代码是否确实发送了任何数据?您可能需要研究.NET 4新的
CopyTo()
stream方法,其中还提到:“将AllowWriteStreamBuffering设置为true可能会在上载大型数据集时导致性能问题,因为数据缓冲区可能会使用所有可用内存。”是,我们尝试了这一点,但仍然面临着将其设置为true或false的挑战。我希望真正的解决方案不是使用PUT或POST进行更新,而是使用更低级的技术,如WCF或POS(普通的Ole套接字lol)。@pearcewg:如果你找到了一种可靠的方法让它工作,那么就给你的问题(或你自己的答案!)添加一个更新——我也很好奇,以后有参考资料就好了;-)我们最终放弃了这个,取而代之的是通过WCF上传,效果非常好!我建议您也采用同样的解决方案。@pearcewg:很酷,很高兴知道。谢谢你上的是什么课?