/// <summary> /// 根据页面对象和上传文件临时目录文件夹,获取一个文件上传上下文类实例 /// </summary> /// <remarks>用户在页面上传初始化上传会话,要求页面每次刷新时均用此方法初始化一个上传上下文</remarks> /// <param name="page">页面对象</param> /// <param name="TempFileDir">文件存放临时文件夹</param> /// <returns>文件上传上下文</returns> public static UploadContext InitUploadContext(System.Web.UI.Page page, string TempFileDir) { UploadContext context = new UploadContext(page, TempFileDir); HttpContext.Current.Cache.Add(context.GUID, context, null, DateTime.Now.AddDays(10), TimeSpan.Zero, CacheItemPriority.High, null); return context; }
/// <summary> /// 分析数据,若是文件,则写入文件,在上传上下文件记录参数 /// </summary> /// <remarks> /// 算法说明:若上一个文件已结束,一、则查找新文件标志符,没找到则退出,找到又分两种情况:1、文件在当前块内结束,则写文件,关闭文件,回到开始继续查找文件标志, /// 2、文件在当前块内没结束,则写文件,并退出处理过程 /// 二、上一个文件未结束,则找文件结束标志,然后又分两种情况:1、找到:当前文件结束,写文件,关闭文件,回到开始,继续分析处理数据, /// 2、没找到,则文件还没结束,则写文件,退出处理过程 /// </remarks> /// <param name="buffer">数据块</param> /// <param name="startIndex">有效数据起始索引</param> /// <param name="maxLength">有效数据结束索引</param> /// <param name="uploadContext">文件上传处理上下文</param> /// <returns>应预留数据长度,防止边界(如文件说明,内容分隔符)位于两个数据块中,若不能确定预留长,则预留 /// 全局常量splitLength所指示的长度</returns> public int ReadData(byte[] buffer, int startIndex, int maxLength, UploadContext uploadContext) { while (true) { if (m_finished) { _fileInfo = GetFileInfo(buffer, startIndex, maxLength); if ((_fileInfo.PathFileName == null) || (_fileInfo.PathFileName.Trim() == ""))//没有找到文件标志 { RewriteRequest(buffer, startIndex, maxLength - startIndex - splitLength); return splitLength; } uploadContext.FileConIds = ArrayAddItem(uploadContext.FileConIds, _fileInfo.FileControl); uploadContext.FileNames = ArrayAddItem(uploadContext.FileNames, _fileInfo.PathFileName); RewriteRequest(buffer, startIndex, _fileInfo.startIndex - startIndex + 10); fs = File.Create(uploadContext.TmepFileDir + uploadContext.GUID + uploadContext.FileNames.Length.ToString() + GetFileName(_fileInfo.PathFileName)); if (_fileInfo.endIndex > -1) { m_finished = true; fs.Write(buffer, _fileInfo.startIndex, _fileInfo.endIndex - _fileInfo.startIndex); fs.Close(); startIndex = _fileInfo.endIndex; } else { m_finished = false; if (maxLength - _fileInfo.startIndex > splitLength) { fs.Write(buffer, _fileInfo.startIndex, maxLength - _fileInfo.startIndex - splitLength); return splitLength; } else { return maxLength - _fileInfo.startIndex; //防止将标志写入了文件 } } } else { _fileInfo.endIndex = DestTag(buffer, m_boundary, startIndex, maxLength); if (_fileInfo.endIndex > -1) //已结束 { _fileInfo.endIndex -= 2; //去掉数据区后的回车换行符 m_finished = true; fs.Write(buffer, startIndex, _fileInfo.endIndex - startIndex); fs.Close(); startIndex = _fileInfo.endIndex; } else { m_finished = false; //当前数据块中,文件体未结束 if (maxLength - startIndex > splitLength) { fs.Write(buffer, startIndex, maxLength - startIndex - splitLength); return splitLength; } else { return maxLength - startIndex; } } } } }