标签:
UpfileResult result = new UpfileResult();
try
{
//先把文件预读到内存里,同时计算上传进度
IServiceProvider provider = (IServiceProvider)HttpContext.Current;
// 返回 HTTP 请求正文已被读取的部分。
HttpWorkerRequest request = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
// 获取上传大小
long length = long.Parse(request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));
CheckFileSize(length, info);
int bytesRead = 0; // 已读数据大小
int read; // 当前读取的块的大小
int count = 8192; // 分块大小
byte[] buffer; // 保存所有上传的数据
byte[] tempBuff = null;
if (request != null)
{
tempBuff = request.GetPreloadedEntityBody();
}
if (tempBuff != null)
{
buffer = new byte[length];
// 分块大小
count = tempBuff.Length;
// 将已上传数据复制过去
Buffer.BlockCopy(tempBuff, 0, buffer, bytesRead, count);
// 开始记录已上传大小
bytesRead = tempBuff.Length;
//计算当前上传文件的百分比
long percent = bytesRead * 100 / length;
SetPercent(SessionId, percent);
int ii = 0;
// 循环分块读取,直到所有数据读取结束
while (request.IsClientConnected() && !request.IsEntireEntityBodyIsPreloaded() && bytesRead < length)
{
// 如果最后一块大小小于分块大小,则重新分块
if (bytesRead + count > length)
{
count = (int)(length - bytesRead);
tempBuff = new byte[count];
}
// 分块读取
read = request.ReadEntityBody(tempBuff, count);
// 复制已读数据块
Buffer.BlockCopy(tempBuff, 0, buffer, bytesRead, read);
// 记录已上传大小
bytesRead += read;
ii++;
if (ii % 10 == 0)
{
//计算当前上传文件的百分比
percent = bytesRead * 100 / length;
SetPercent(SessionId, percent);
}
if (read == 0)
{
//如果前面读取过文件(Global.asax中的360验证),这里就读不到数据,需避免进入死循环
break;
}
}
if (request.IsClientConnected() && !request.IsEntireEntityBodyIsPreloaded())
{
// 传入已上传完的数据 //
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = request.GetType();
while ((type != null) && (type.FullName != "System.Web.Hosting.ISAPIWorkerRequest"))
{
type = type.BaseType;
}
if (type != null)
{
type.GetField("_contentAvailLength", bindingFlags).SetValue(request, buffer.Length);
type.GetField("_contentTotalLength", bindingFlags).SetValue(request, buffer.Length);
type.GetField("_preloadedContent", bindingFlags).SetValue(request, buffer);
type.GetField("_preloadedContentRead", bindingFlags).SetValue(request, true);
}
// 表示上传已结束
}
}
HttpPostedFile imgFile = _request.Files[0];
string fileName = imgFile.FileName;
UpLoadFile(result, imgFile, fileName, info, SessionId);
SetPercent(SessionId, 100);
return result;
}
catch (Exception ex)
{
result.IsOk = false;
result.ErrMsg = ex.Message;
return result;
}
/// <summary>
/// 支持断点下载
/// </summary>
/// <param name="Request"></param>
/// <param name="Response"></param>
/// <param name="filePath">文件的物理地址</param>
private void Down(HttpRequest Request, HttpResponse Response, string filePath)
{
/*断点下载与普通模式不一样的是:
断点下载的请求头信息里面增加一个属性 RANGE: bytes=100000-
响应头里 增加一个属性 Content-Range=bytes 100000-19999/20000
返回状态码为206(Partial Content)
表示头500个字节:Range: bytes=0-499
表示第二个500字节:Range: bytes=500-999
表示最后500个字节:Range: bytes=-500
表示500字节以后的范围:Range: bytes=500-
第一个和最后一个字节:Range: bytes=0-0,-1
同时指定几个范围:Range: bytes=500-600,601-999
*/
// 打开文件
using (Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
// 获取文件的大小
long fileSize = fileStream.Length;
string range = Request.Headers["Range"];
Response.Clear();
Response.AddHeader("Accept-Ranges", "bytes");
Response.AddHeader("Connection", "Keep-Alive");
Response.Buffer = false;
//数据包大小
int pack = 10240; //10Kb
int sleep = 0;
if(this.Speed.HasValue)
{
sleep = (int)Math.Floor(1000.0 * 10 / this.Speed.Value);
}
long begin = 0;
long end = fileSize - 1;
if (!string.IsNullOrEmpty(range))
{
//获取请求的范围,如果有多个范围,暂时只处理第一个,Range: bytes=500-600,601-999
range = range.Replace("bytes=", "");
range = range.Split(‘,‘)[0];
string[] region = range.Split(‘-‘);
string startPoint = region[0].Trim();
string endPoint = region[1].Trim();
if (startPoint == "")
{
long.TryParse(endPoint, out end);
begin = fileSize - end;
end = fileSize - 1;
}
else if (endPoint == "")
{
long.TryParse(startPoint, out begin);
end = fileSize - 1;
}
else
{
long.TryParse(startPoint, out begin);
long.TryParse(endPoint, out end);
}
Response.StatusCode = 206;
Response.AddHeader("Content-Range", string.Format("bytes {0}-{1}/{2}", begin, end, fileSize));
}
//以字节流返回数据
Response.ContentType = "application/octet-stream";
//Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + HttpUtility.UrlEncode(Request.ContentEncoding.GetBytes(this.FileName)) + "\"");
long size = end - begin + 1;
Response.AddHeader("Content-Length", size.ToString());
// 创建一比特数组
byte[] buffer = new Byte[pack];
fileStream.Position = begin; //设置当前流位置
// 当文件大小大于0是进入循环
while (size > 0)
{
// 判断客户端是否仍连接在服务器
if (Response.IsClientConnected)
{
// 获取缓冲区中的总字节数.
int length = fileStream.Read(buffer, 0, pack);
// 写入数据
Response.OutputStream.Write(buffer, 0, length);
// 将缓冲区的输出发送到客户端
Response.Flush();
buffer = new Byte[pack];
size = size - length;
if (sleep > 0)
{
Thread.Sleep(sleep);
}
}
else
{
//当用户断开后退出循环
size = -1;
}
}
}
}
文件的断点上传,待补充
标签:
原文地址:http://www.cnblogs.com/wj033/p/5547629.html