/// <summary> /// 是否是断点续传 /// </summary> /// <param name="name"></param> /// <param name="fileSize"></param> /// <param name="lastModifiedDate"></param> /// <returns></returns> public JsonResult IsContinue(string name, long fileSize, string lastModifiedDate, string app = "epm") { using (ClientProxyFileServer proxy = new ClientProxyFileServer(ProxyEx(Request))) { //存储文件信息以便对比 FileGuid fg = new FileGuid(); fg.App = app; fg.FId = Guid.NewGuid().ToString(); fg.FileSize = fileSize; fg.LastModifiedDate = lastModifiedDate; fg.Name = name; fg.RecordTime = DateTime.Now; var result = proxy.AddFileGuid(fg); fg = result.Data; var tempFiles = proxy.GetTempFiles(app, name, lastModifiedDate, fileSize); //存在临时文件,代表可以断点续传 if (tempFiles.Data != null && tempFiles.Data.Count() > 0) { //依据块顺序 var fileList = tempFiles.Data.OrderBy(i => i.Chunk); var tempModel = tempFiles.Data.FirstOrDefault(); //如果超过两天,清除临时文件,重新上传 var ts = DateTime.Now - tempModel.UploadTime; if (ts.Hours > deleteHour.ToInt32Req()) { //删除临时块文件信息 proxy.DeleteTempFile(fileList.Select(i => i.Id).ToList()); return(Json(new { size = 0, flag = true, fid = fg.Id }, JsonRequestBehavior.AllowGet)); } var tempPath = tempModel.ChunkPath.Replace(tempModel.ChunkName, "") + "Temp_" + tempModel.FileName; using (FileStream fsw = new FileStream(tempPath, FileMode.Create, FileAccess.Write)) { BinaryWriter bw = new BinaryWriter(fsw); //合并文件,计算临时文件大小 foreach (var temp in fileList) { bw.Write(System.IO.File.ReadAllBytes(temp.ChunkPath)); //打开一个文件读取流信息,将其写入新文件 bw.Flush(); //清理缓冲区 } } FileInfo file = new FileInfo(tempPath); return(Json(new { size = (int)file.Length, flag = true, fid = fg.Id }, JsonRequestBehavior.AllowGet)); //清空临时为了计算大小合并的文件 } return(Json(new { size = 0, flag = true, fid = fg.Id }, JsonRequestBehavior.AllowGet)); } }
/// <summary> /// 分块断点续传,多文件 /// </summary> /// <param name="request"></param> /// <returns></returns> private object UploadFileByChunk(HttpRequestBase request) { //断点续传 string app = Request["app"]; string name = Request["name"]; int fId = Request["fId"].ToInt32Req(); int chunk = Request["chunk"].ToInt32Req(); //当前分块 int chunks = Request["chunks"].ToInt32Req(); //总的分块数量 // 是否上传模型 string bim = request["isbim"]; bool isbim = "true".Equals((string.IsNullOrWhiteSpace(bim) ? "false" : bim).ToLower()); foreach (string file in Request.Files) { if (!string.IsNullOrEmpty(file)) { using (ClientProxyFileServer proxy = new ClientProxyFileServer(ProxyEx(Request))) { //取得文件对比信息 FileGuid fg = proxy.GetFileGuid(fId).Data; HttpPostedFileBase postedFile = Request.Files[file]; //获取客户端上载文件的集合 string fileName = Path.GetFileNameWithoutExtension(name); //获取客户端上传文件的名称 string extensionName = Path.GetExtension(name).ToLower(); //获取客户端上传文件的后缀 string newFileName = name; //获取文件存储目录 var configList = proxy.GetConfig(app); FileConfig config = null; if (isbim) { config = configList.Data.FirstOrDefault(i => i.FileTypeDirectory == "model"); } else { config = configList.Data.FirstOrDefault(i => i.FileTypeExtension.Contains(extensionName) && i.FileTypeDirectory != "model"); } if (config == null) { config = configList.Data.FirstOrDefault(i => i.FileTypeExtension.Contains(".*")); //return (new { flag = false, result = "不允许上传此类型的文件" }); } var pathList = CreatePath(config); string tempPath = pathList[0]; string filePath = pathList[1]; //分块 if (chunks > 1) { newFileName = chunk + "_" + GetRamCode() + "_" + fileName + extensionName; //按文件块重命名块文件 } string chunkPath = tempPath + "\\" + newFileName; //将块文件和临时文件夹路径绑定 postedFile.SaveAs(chunkPath); //保存临时块上载文件内容 //临时块文件入库 FileInfo chunkFile = new FileInfo(chunkPath); TempFiles tf = new TempFiles(); tf.App = app; tf.Chunk = chunk; tf.ChunkName = newFileName; tf.ChunkPath = chunkPath; tf.Chunks = chunks; tf.ChunkSize = (int)chunkFile.Length; tf.FileGuid = Guid.NewGuid().ToString(); tf.FileLastModifiedDate = fg.LastModifiedDate; tf.FileName = name; tf.FileSize = fg.FileSize; tf.UploadTime = DateTime.Now; tf.RequetURL = Request.UrlReferrer.ToString(); tf.IP = request.UserHostAddress; tf.Browser = request.Browser.Browser; //TODO:可以在此处获取每一个块文件的md5在检测是否可以续传时返回少一个块文件的长度,然后对比续传的第一个块的md5来实现去重 tf = proxy.AddTempFile(tf).Data; //最后一个块,执行合并 if (chunks > 1 && chunk + 1 == chunks) { var tempFiles = proxy.GetTempFiles(app, name, fg.LastModifiedDate, fg.FileSize); var fileList = tempFiles.Data.OrderBy(i => i.Chunk); string reName = Guid.NewGuid().ToString() + name; string fullPath = filePath + "\\" + reName; using (FileStream fsw = new FileStream(fullPath, FileMode.Create, FileAccess.Write)) { BinaryWriter bw = new BinaryWriter(fsw); // 遍历文件合并 foreach (var temp in fileList) { //打开一个文件读取流信息,将其写入新文件 bw.Write(System.IO.File.ReadAllBytes(temp.ChunkPath)); System.IO.File.Delete(temp.ChunkPath); //删除临时块文件信息,以避免临时文件越来越大 bw.Flush(); //清理缓冲区 } } //正式文件入库 Files sf = new Files(); sf.App = app; sf.Day = DateTime.Now.ToString("yyyyMMdd").ToInt32Req();; sf.Extension = extensionName; sf.FilePath = fullPath; sf.FileSize = fg.FileSize; sf.FileType = config.FileTypeName; sf.Guid = fg.FId; sf.IsDelete = false; sf.LastModifiedDate = fg.LastModifiedDate; sf.Month = DateTime.Now.ToString("yyyyMM").ToInt32Req();; sf.Name = name; sf.ReName = reName; sf.RequetURL = Request.UrlReferrer.ToString(); sf.UploadTime = DateTime.Now; sf.Year = DateTime.Now.Year; sf.UserDescription = ""; sf.IP = request.UserHostAddress; sf.Browser = request.Browser.Browser; string md5 = GetMD5HashFromFile(fullPath); sf.MD5 = md5; sf.VirtualURL = (filePath.Replace(config.ParentPath, "/").Replace("\\", "/") + "/" + reName); sf = proxy.AddFile(sf).Data; //删除临时块文件信息 proxy.DeleteTempFile(fileList.Select(i => i.Id).ToList()); //删除fileguid对比信息 proxy.DeleteFileGuid(fg); return(new { flag = true, type = "file", file = sf }); } return(new { flag = true, type = "chunk", chunk = tf }); } } } return(new { flag = false, result = "文件上传失败" }); }