C# 使用memorystream接收内存不足异常
我正在尝试编写一个应用程序,它将与开源媒体管理平台Kaltura一起工作。Kaltura提供了一些C#客户端库,可以与他们的web API对话,我可以与服务器对话并成功上传视频。我遇到的问题是,一旦文件达到一定大小,我就会收到内存不足异常,程序就会崩溃。我想尝试解决这个问题,并将改进后的代码提交回开源项目,但由于对C#不熟悉,我不知道从哪里开始。有没有比memorystream更好的方法来做他们正在做的事情 提前谢谢C# 使用memorystream接收内存不足异常,c#,memory-management,kaltura,C#,Memory Management,Kaltura,我正在尝试编写一个应用程序,它将与开源媒体管理平台Kaltura一起工作。Kaltura提供了一些C#客户端库,可以与他们的web API对话,我可以与服务器对话并成功上传视频。我遇到的问题是,一旦文件达到一定大小,我就会收到内存不足异常,程序就会崩溃。我想尝试解决这个问题,并将改进后的代码提交回开源项目,但由于对C#不熟悉,我不知道从哪里开始。有没有比memorystream更好的方法来做他们正在做的事情 提前谢谢 //Problematic code private void PostMu
//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();
}
//有问题的代码
私有void PostMultiPartWithFiles(HttpWebRequest请求、KalturaParams kparams、KalturaFiles kFile)
{
字符串边界=“------------------------------------”+DateTime.Now.Ticks.ToString(“x”);
request.ContentType=“多部分/表单数据;boundary=“+boundary;
//使用内存流,因为当我们有多个文件时,我们不知道请求的内容长度
MemoryStream memStream=新的MemoryStream();
字节[]缓冲区;
int字节读取=0;
StringBuilder sb=新的StringBuilder();
sb.追加(“--”+边界+”\r\n”);
foreach(kparams中的KeyValuePair参数)
{
sb.Append(“内容处置:表单数据;名称=\”“+param.Key+\”“+”\r\n”);
sb.追加(“\r\n”);
sb追加(参数值);
sb.追加(“\r\n--”+boundary+”\r\n”);
}
buffer=Encoding.UTF8.GetBytes(sb.ToString());
memStream.Write(buffer,0,buffer.Length);
foreach(kfiles中的KeyValuePair文件)
{
sb=新的StringBuilder();
FileStream FileStream=file.Value;
sb.Append(“内容处置:表单数据;名称=\”“+文件.Key+”\“文件名=\”“+路径.GetFileName(fileStream.name)+“\”“+”\r\n”);
sb.Append(“内容类型:应用程序/八位字节流”+”\r\n”);
sb.追加(“\r\n”);
//编写当前字符串生成器内容
buffer=Encoding.UTF8.GetBytes(sb.ToString());
memStream.Write(buffer,0,buffer.Length);
//写入文件内容
buffer=newbyte[checked((uint)Math.Min(4096,(int)fileStream.Length));
字节读取=0;
而((bytesRead=fileStream.Read(buffer,0,buffer.Length))!=0)
memStream.Write(缓冲区,0,字节读取);
buffer=Encoding.UTF8.GetBytes(“\r\n--”+boundary+”\r\n”);
memStream.Write(buffer,0,buffer.Length);
}
request.ContentLength=memStream.Length;
Stream requestStream=request.GetRequestStream();
//将内存流写入请求流
memStream.Seek(0,SeekOrigin.Begin);
buffer=newbyte[checked((uint)Math.Min(4096,(int)memStream.Length));
字节读取=0;
while((bytesRead=memStream.Read(buffer,0,buffer.Length))!=0)
写入(缓冲区,0,字节读取);
requestStream.Close();
memStream.Close();
}
这里有一个版本,大致上我是怎么写的。它只编译,但我没有测试它。请注意StreamWriter的使用和请求流的直接使用
public class SendStuff
{
private readonly HttpWebRequest _request;
private readonly Dictionary<string, string> _kparams;
private readonly Dictionary<string, FileStream> _kfiles;
readonly string _boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
public SendStuff(
HttpWebRequest request,
Dictionary<string, string> kparams,
Dictionary<string, FileStream> kfiles)
{
_request = request;
_kparams = kparams;
_kfiles = kfiles;
_request.ContentType = "multipart/form-data; boundary=" + _boundary;
}
public void Do()
{
// Based on HTTP 1.1, if the server can determine the content length, it need not insist on
// us sending one. If you are talking
// to a "special" server, construct the headers beforehand, measure their length
// and identify the file lengths of the files to be sent.
using (var reqStream = _request.GetRequestStream())
using (var writer = new StreamWriter(reqStream))
{
writer.NewLine = "\r\n";
WriteBoundary(writer);
WriteParams(writer);
foreach (var file in _kfiles)
{
writer.WriteLine("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"",
file.Key,
Path.GetFileName(file.Value.Name));
writer.WriteLine("Content-Type: application/octet-stream");
writer.WriteLine();
WriteTheFileContent(reqStream, file.Value);
WriteBoundary(writer);
}
}
}
private static void WriteTheFileContent(Stream reqStream, Stream fileStream)
{
int bytesRead;
var buffer = new byte[4096];
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
reqStream.Write(buffer, 0, bytesRead);
}
private void WriteParams(StreamWriter writer)
{
foreach (var param in _kparams)
{
writer.WriteLine("Content-Disposition: form-data; name=\"{0}\"", param.Key);
writer.WriteLine();
writer.WriteLine(param.Value);
WriteBoundary(writer);
}
}
private void WriteBoundary(TextWriter writer)
{
writer.WriteLine("\r\n--{0}\r\n", _boundary);
}
}
公共类SendStuff
{
私有只读HttpWebRequest\u请求;
专用只读词典_kparams;
专用只读词典_kfiles;
只读字符串_boundary=“------------------------------------”+DateTime.Now.Ticks.ToString(“x”);
公共物品(
HttpWebRequest请求,
字典kparams,
字典(kfiles)
{
_请求=请求;
_kparams=kparams;
_k文件=k文件;
_request.ContentType=“多部分/表单数据;boundary=“+\u boundary;
}
公营部门
{
//基于HTTP 1.1,如果服务器可以确定内容长度,则无需坚持
//如果你在说话,我们就派一个
//对于“特殊”服务器,事先构造头文件,测量其长度
//并确定要发送的文件的文件长度。
使用(var reqStream=\u request.GetRequestStream())
使用(var编写器=新StreamWriter(reqStream))
{
writer.NewLine=“\r\n”;
书面材料(作者);
书写图(书写者);
foreach(文件中的var文件)
{
WriteLine(“内容处置:表单数据;名称=\”{0}\“文件名=\”{1}\”,
file.Key,
GetFileName(file.Value.Name));
WriteLine(“内容类型:应用程序/八位字节流”);
writer.WriteLine();
WriteFileContent(reqStream,file.Value);
书面材料(作者);
}
}
}
私有静态void WriteTheFileContent(流请求流、流文件流)
{
int字节读取;
var buffer=新字节[4096];
而((bytesRead=fileStream.Read(buffer,0,buffer.Length))!=0)
请求流写入(缓冲区,0,字节读取);
}
私有void WriteParams(StreamWriter编写器)
{
foreach(变量参数在_kparams中)
{
WriteLine(“内容处置:表单数据;名称=\”{0}\”,param.Key);
writer.WriteLine();
writer.WriteLine(参数值);
书面材料(作者);
}
}
私有无效WriteBondary(TextWriter)
{
writer.WriteLine(“\r\n--{0}\r\n”,_边界);
}
}
看起来您正在加载整套视频