【发布时间】:2012-11-05 21:05:40
【问题描述】:
我正在尝试编写一个可以与开源媒体管理平台 Kaltura 一起使用的应用程序。 Kaltura 提供了一些与他们的 Web API 对话的 C# 客户端库,我已经能够与服务器对话并成功上传视频。我遇到的问题是,一旦文件达到一定大小,我就会收到内存不足异常并且程序崩溃。我想尝试解决这个问题并将改进的代码提交回开源项目,但是对于 C# 来说是新手,我不知道从哪里开始。有没有比 memorystream 更好的方法来做他们正在做的事情?
提前致谢。
//Problematic code
private void PostMultiPartWithFiles(HttpWebRequest request, KalturaParams kparams, KalturaFiles kfiles)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
request.ContentType = "multipart/form-data; boundary=" + boundary;
// use a memory stream because we don't know the content length of the request when we have multiple files
MemoryStream memStream = new MemoryStream();
byte[] buffer;
int bytesRead = 0;
StringBuilder sb = new StringBuilder();
sb.Append("--" + boundary + "\r\n");
foreach (KeyValuePair<string, string> param in kparams)
{
sb.Append("Content-Disposition: form-data; name=\"" + param.Key + "\"" + "\r\n");
sb.Append("\r\n");
sb.Append(param.Value);
sb.Append("\r\n--" + boundary + "\r\n");
}
buffer = Encoding.UTF8.GetBytes(sb.ToString());
memStream.Write(buffer, 0, buffer.Length);
foreach (KeyValuePair<string, FileStream> file in kfiles)
{
sb = new StringBuilder();
FileStream fileStream = file.Value;
sb.Append("Content-Disposition: form-data; name=\"" + file.Key + "\"; filename=\"" + Path.GetFileName(fileStream.Name) + "\"" + "\r\n");
sb.Append("Content-Type: application/octet-stream" + "\r\n");
sb.Append("\r\n");
// write the current string builder content
buffer = Encoding.UTF8.GetBytes(sb.ToString());
memStream.Write(buffer, 0, buffer.Length);
// write the file content
buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
memStream.Write(buffer, 0, bytesRead);
buffer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
memStream.Write(buffer, 0, buffer.Length);
}
request.ContentLength = memStream.Length;
Stream requestStream = request.GetRequestStream();
// write the memorty stream to the request stream
memStream.Seek(0, SeekOrigin.Begin);
buffer = new Byte[checked((uint)Math.Min(4096, (int)memStream.Length))];
bytesRead = 0;
while ((bytesRead = memStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
requestStream.Close();
memStream.Close();
}
【问题讨论】:
-
看起来您正在将整组视频加载到您的内存流中...这肯定会导致您的内存不足异常。您不应将其全部缓冲到内存中,而应直接将其复制到
RequestStream -
这是某种 POST 操作吗?显而易见的问题是代码不直接使用请求流,而是绕道而行。大文件肯定会失败。因此,不要写入 Memorystream,而是写入请求流,然后看看它会带来什么。
标签: c# memory-management kaltura