两周前就想把这点经验记录下来了,由于拖延症上身,直到刚才突然想起这件未完成的任务,今天是1024,在这个特别的日子里,祝所有程序猿兄弟姐妹们节日快乐!

上传功能一直很正常,直到上传了个500多兆的文件,报错提示:

“System.OutOfMemoryException”类型的异常在 mscorlib.dll 中发生,但未在用户代码中进行处理

对于内部用途和新的托管对象,确保要有足够的内存可供分配。
如果要创建数组,请确保大小正确。

由于调用的webservice中的文件上传方法参数为二进制格式,需要把文件流转换为byte格式,所以直接写了byte[] byte = new byte[stream.Length],结果那个大文件就是在这句卡住了,一开始也很蒙圈,已经在配置文件中修改了最大请求的长度为何还会有问题,调试代码发现new byte[]的时候括号内要求参数是一个8位的整数,那个500多兆的文件转为字节后是个9位数,导致byte类型超出索引,于是想到每次实例化一个固定长度的byte,让文件循环写入,写满一个byte就放入数组,然后在服务端在解析这个数组即可,这样就不会存在内存溢出的问题了,下面是示例代码,仅供参考,若要带走,欢迎转发。

脚本部分在上一篇中有代码展示,这里只展示后台和服务端代码了。

1.一般处理程序部分:

public void FileUpload(HttpContext context)
{
WebService ws = new WebService();
ws.Timeout = ; //单位毫秒,1小时 HttpFileCollection files = context.Request.Files;
if (files.Count > )
{
/*获取真实文件名,files[0].FileName这种方法在IE浏览器中上传会带有F://路径*/
string filename = System.IO.Path.GetFileName(files[].FileName);
HttpPostedFile file = files[];
Stream fs = file.InputStream; /*定义object数组,用来存放byte数据*/
object[] obj = new object[] { };
List<object> list = new List<object>();
int offcount = ; /* size:1M,unit:byte */
int LimitSize = ;/*限制大小150M,unit:byte*/
if (fs.Length > LimitSize)
{
context.Response.Write("OutOfSize");
context.Response.End();
return;
}
int filelen = (int)fs.Length;
if (filelen > offcount)
{
long offset = ;
byte[] postArray = new byte[offcount];
int temponum = filelen / offcount;
/*整数部分*/
for (int i = ; i <= temponum; i++)
{
long lkl = filelen;
postArray = new byte[offcount];
fs.Seek(offset, SeekOrigin.Begin);
fs.Read(postArray, , offcount);
list.Add(postArray);
offset += offcount;
}
/*剩余部分*/
if (temponum * offcount < filelen)
{
offcount = filelen - temponum * offcount;
byte[] lpostArray = new byte[offcount];
fs.Seek(offset, SeekOrigin.Begin);
fs.Read(lpostArray, , offcount);
list.Add(lpostArray);
}
}
else
{
byte[] postArray = new byte[file.ContentLength];
fs.Read(postArray, , file.ContentLength);
list.Add(postArray);
}
/*list集合转为object数组*/
obj = list.ToArray();
fs.Flush();
fs.Close();
/*计算文件大小,文件大于1M,单位用M,其他用KB*/
string filesize = string.Empty;
if (filelen > )
{ filesize = Math.Ceiling((double)filelen / (double) / (double)) + "M"; }
else
{ filesize = Math.Ceiling((double)filelen / (double)) + "KB"; } /*为防止流长度溢出byte,固定byte大小放入object数组*/
string result = ws.objUploadFile(obj, "FileFolder", filename);
}
}

2.webservice服务端部分:

  /// <summary>
/// 上传文件
/// </summary>
/// <param name="obj">分割的byte[]数组</param>
/// <param name="path">文件存放文件夹</param>
/// <param name="fileName">文件名字</param>
/// <returns>文件的路径</returns>
[WebMethod(Description = "上传文件,返回路径")]
public string objUploadFile(object[] obj, string path, string fileName)
{
string ReturnPath = string.Empty;
FileStream wf = null;
byte[] fs;
try
{
string _FileName = string.Empty;
string FilePath = "uploadfiles\\document\\" + path;
FilePath = Server.MapPath(FilePath);
if (!Directory.Exists(FilePath))
{
Directory.CreateDirectory(FilePath);
} System.Random rnd = new System.Random();
string tmp = rnd.Next().ToString();
_FileName = "File_" + tmp + "_" + fileName; //文件名加随机数字
wf = new FileStream(FilePath + "\\" + _FileName, FileMode.Append, FileAccess.Write);
if (obj.Length > )
{
for (int i = ; i < obj.Length; i++)
{
fs = (byte[])obj[i];
wf.Write(fs, , fs.Length);
}
}
wf.Close();
wf = null;
ReturnPath = "\\uploadfiles\\document\\" + path + "\\" + _FileName;
}
catch
{
ReturnPath = string.Empty;
}
finally
{
}
return ReturnPath;
}

希望本文能够帮助遇到同样问题的同学们,如有不妥之处,欢迎指正。

文件上传之--内存溢出(System.OutOfMemoryException)的更多相关文章

  1. .Net内存溢出 System.OutOfMemoryException

    内存溢出常见的情况和处理方式: http://outofmemory.cn/c/dotNet-outOfMemoryException MSDN中关于processModel的文档 https://m ...

  2. 内存溢出System.OutOfMemoryException

    .Net 内存溢出(System.OutOfMemoryException)的常见情况和处理方式总结 在什么情况下会出现OutOfMemonryException呢? 在我们试图新建一个对象时,而垃圾 ...

  3. ASP.NET MVC HttpPostedFileBase文件上传

    HttpPostedFileBase文件上传,支持多文件一次上传,如有图片,则支持略缩图保存 文件传输信息封装 /// <summary> /// 文件生成方式 /// </summ ...

  4. 文件上传下载(C#,web,asp.net)

    目的:在浏览器页面启动上传下载CS软件,实现文件的批量下载与上传. 技术路线: 开发上传下载客户端CS程序与注册程序,压缩放到服务器端指定位置: 开发服务器端程序用以接收上传请求,压缩放到服务器端: ...

  5. jsp 文件上传操作

    文件上传 1:完成一个文件上传的功能 index.jsp 注意更换form表单的enctype enctype就是encodetype就是编码类型的意思. multipart/form-data是指表 ...

  6. 用SpringMVC实现的上传下载方式二(多文件上传)

    参考来源:      http://blog.csdn.net/qq_32953079/article/details/52290208 1.导入相关jar包 commons-fileupload.j ...

  7. 文件上传报错:Unknown: file created in the system's temporary directory

    nginx+php下文件上传成功,但会有错误提示如下: <b>Notice</b>:  Unknown: file created in the system's tempor ...

  8. webform文件上传、图片水印、验证码

    文件上传: 所用控件:FileUpload 使用时的思路: 1.判断用户是否选中了文件 FileUpload.FileName获取选中的文件名,判断长度,如果长度大于零就代表已经选择了文件 JS端:通 ...

  9. Webform(文件上传)

    1.HTML编码: <input type="file" /> 2.控件:FileUpload 它是用来选择要上传的文件,还需要一个按钮来将选中的文件上传到服务器上 s ...

随机推荐

  1. javascript中用setAttribute给元素添加colspan属性无效

    先附上代码 var tr=document.createElement('TR'); var td=document.createElement('TD'); td.setAttribute('col ...

  2. Eslint配置

    //ESLint 4.5.0,参考了eslint官方以及alloyteam团队配置 module.exports = { parser: 'babel-eslint', parserOptions: ...

  3. vue学习日志(一):vue的优势

    vue的中文官方文档里面有对比其他框架的具体介绍,这里只是做一个概括总结: 1,在 Vue 应用中,组件的依赖是在渲染过程中自动追踪的,所以系统能精确知晓哪个组件确实需要被重渲染.你可以理解为每一个组 ...

  4. CSS3动画效果之transition

    CSS3中有两种方式实现动画,transition和animation+@keyframe. 两者的作用机制不一样:transition定义在可能要进行动画的元素上,对某些CSS属性进行监听,一旦CS ...

  5. 想做iPhoneX抢购活动?压测大师先教你优化网站后台

    北京时间9月13日凌晨1点,iPhone 10周年,在Apple Park乔布斯剧院,苹果发布了三款新iPhone.全面屏iPhone X来袭,这款被定义为未来的智能手机黑科技满满:全面屏,无线充电. ...

  6. linux c编程:初识进程与线程

    p { margin-bottom: 0.25cm; line-height: 120% } (一) 认识进程 在Linux系统中,每一个进程都有自己的ID,就如同人的身份证一样.linux中有一个数 ...

  7. js数组、内置对象、自定义对象

    [js中的数组] 1.数组的基本概念? 数组是在内存空间中连续存储的一组有序数据的集合 元素在数组中的顺序,称为下标.可以使用下表访问数字的每个元素. 2.如何声明一个数组? ① 使用字面量声明: 在 ...

  8. 【Beta阶段】第一次scrum meeting

    Coding/OSChina 地址 1. 会议内容 学号 主要负责的方向 昨日任务 昨日任务完成进度 接下去要做 9 9 PM 博客编写,会议总结,代码整理 100% 准备下一次会议内容,并对已完成的 ...

  9. 201521123075 《Java程序设计》第6周学习总结

    1. 本周学习总结 2. 书面作业 1.clone方法 1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么? 答:第一,要覆盖clon ...

  10. 201521123038 《Java程序设计》 第三周学习总结

    201521123038 <Java程序设计> 第三周学习总结 1. 本周学习总结 附大图链接 http://naotu.baidu.com/file/5774caa2be710afbc0 ...