/// <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; } } } } }
/// <summary> /// 获取文件上传信息 /// </summary> /// <param name="buffer">数据块</param> /// <param name="startIndex">起始位置</param> /// <param name="maxLength">最大有效长度</param> /// <returns>如找到文件信息,则返回文件信息,否则,文件信息的所有字段为空</returns> public UpFileInfo GetFileInfo(byte[] buffer, int startIndex, int maxLength) { UpFileInfo lfileInfo = new UpFileInfo(); while (startIndex < maxLength) { int splitPos = DestTag(buffer, m_boundary, startIndex, maxLength); //读取分隔符 if (splitPos < startIndex) break; int lineEndPos = DestTag(buffer, m_crlf, splitPos + m_boundary.Length + 2, maxLength); if (lineEndPos < splitPos + m_boundary.Length) break; int signFilePos = DestTag(buffer, this.m_constName, splitPos + m_boundary.Length + 2, lineEndPos); if (signFilePos > splitPos + m_boundary.Length - 1) //找到文件标志示“fileName="” { string Content_Disposition = this.m_encoding.GetString(buffer, splitPos + m_boundary.Length + 2, lineEndPos - splitPos - m_boundary.Length - 2).ToLower(); int nextLineEnd = DestTag(buffer, ConcatArray(m_crlf, m_crlf), lineEndPos + 2, maxLength); string Content_Type = this.m_encoding.GetString(buffer, lineEndPos + 2, nextLineEnd - lineEndPos - 2).ToLower(); string[] Disp = Content_Disposition.Split(new char[] { '\"' }); lfileInfo.FileControl = Disp[1]; lfileInfo.PathFileName = Disp[3]; string[] FileType = Content_Type.Split(new char[] { ':' }); lfileInfo.FileType = FileType[1]; lfileInfo.startIndex = nextLineEnd + 4; lfileInfo.endIndex = DestTag(buffer, m_boundary, lfileInfo.startIndex, maxLength); if (lfileInfo.endIndex > 0) lfileInfo.endIndex -= 2; //去掉数据区后的回车换行符 break; } startIndex = lineEndPos; } return lfileInfo; }