Beispiel #1
0
        /// <summary>
        /// 合并文件
        /// </summary>
        /// <returns></returns>
        public JsonResult MergeFiles(string md5, string filename)
        {
            try
            {
                //源数据文件夹
                string sourcePath = getFileMD5Folder();
                //合并后的文件路径
                string targetFilePath = sourcePath + Path.GetExtension(filename);
                // 目标文件不存在,则需要合并
                if (!System.IO.File.Exists(targetFilePath))
                {
                    if (!Directory.Exists(sourcePath))
                    {
                        return(Json(JResult.Error("未找到对应的文件片")));
                    }

                    MergeDiskFile(sourcePath, targetFilePath);
                }

                var vaild = VaildMergeFile(targetFilePath);
                if (!vaild.Result)
                {
                    return(Json(vaild));
                }
                DeleteFolder(sourcePath);
                FileUploadInfo fileResult = OwnBusiness(targetFilePath);
                return(Json(JResult.Success(fileResult)));
            }
            catch (Exception ex)
            {
                return(Json(JResult.Error(ex.Message)));
            }
        }
Beispiel #2
0
        /// <summary>
        /// 校验合并后的文件
        /// <para>1.是否没有漏掉块(chunk)</para>
        /// <para>2.检测文件大小是否跟客户端一样</para>
        /// <para>3.检查文件的MD5值是否一致</para>
        /// </summary>
        /// <param name="targetPath"></param>
        /// <returns></returns>
        private CommResult VaildMergeFile(string targetPath)
        {
            var clientFileName = Request.Form["filename"];

            // 文件字节总数
            var fileTotalSize = Convert.ToInt32(Request.Form["fileTotalSize"]);

            var targetFile      = new FileInfo(targetPath);
            var streamTotalSize = targetFile.Length;

            try
            {
                if (streamTotalSize != fileTotalSize)
                {
                    throw new Exception("[" + clientFileName + "]文件上传时发生损坏,请重新上传");
                }

                // 对文件进行 MD5 唯一验证
                var identifier = Request.Form["md5"];
                var fileMd5    = GetMD5HashFromFile(targetPath);
                if (!fileMd5.Equals(identifier))
                {
                    throw new Exception("[" + clientFileName + "],文件MD5值不对等");
                }
                return(JResult.Success());
            }
            catch (Exception ex)
            {
                // 删除本地错误文件
                System.IO.File.Delete(targetPath);
                return(JResult.Error(ex.Message));
            }
        }
Beispiel #3
0
        /// <summary>
        /// 文件分块上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <param name="chunk">当前分片在上传分片中的顺序(从0开始)</param>
        /// <returns></returns>
        public JsonResult ChunkUpload(HttpPostedFileBase file, int chunk = 0)
        {
            try
            {
                var md5Folder = getFileMD5Folder();
                // 存在分片参数
                if (Request.Form.AllKeys.Any(t => t == "chunk"))
                {
                    var webAppUpNumsOfLoop = HMSUtil.GetConfig(EnuInitCode.WebAppUpNumsOfLoop.ToString()).ToInt(10);
                    // 是10的倍数就休眠几秒(数据库设置的秒数)
                    if (chunk % webAppUpNumsOfLoop == 0)
                    {
                        var webAppUpPauseTimesOfLoop = HMSUtil.GetConfig(EnuInitCode.WebAppUpPauseTimesOfLoop.ToString()).ToInt(10);
                        Thread.Sleep(webAppUpPauseTimesOfLoop);
                    }

                    //建立临时传输文件夹
                    if (!Directory.Exists(md5Folder))
                    {
                        Directory.CreateDirectory(md5Folder);
                    }

                    var chunkFilePath = md5Folder + "/" + chunk;
                    if (file != null)
                    {
                        file.SaveAs(chunkFilePath);
                    }
                    else
                    {
                        byte[] byts = new byte[Request.InputStream.Length];
                        Request.InputStream.Read(byts, 0, byts.Length);
                        var createChunkFile = System.IO.File.Create(chunkFilePath);
                        createChunkFile.Write(byts, 0, byts.Length);
                        createChunkFile.Close();
                    }
                    var jsucess = JResult.Success();
                    jsucess.Code = chunk.ToStr();
                    // 当前片数等于总片数时,则返回切片完成的标识
                    var chunks = Request.Form["chunks"].ToInt();
                    if ((chunks - 1) == chunk)
                    {
                        jsucess.Message = "chunked";
                    }
                    return(Json(jsucess, JsonRequestBehavior.AllowGet));
                }
                else
                {
                    //没有分片直接保存
                    string path = md5Folder + Path.GetExtension(file.FileName);
                    file.SaveAs(path);
                    return(Json(JResult.Success("chunked")));
                }
            }
            catch (Exception ex)
            {
                return(Json(JResult.Error(ex.Message), JsonRequestBehavior.AllowGet));
            }
        }
Beispiel #4
0
        /// <summary>
        /// 校验合并后的文件
        /// <para>1.是否没有漏掉块(chunk)</para>
        /// <para>2.检测文件大小是否跟客户端一样</para>
        /// <para>3.检查文件的MD5值是否一致</para>
        /// </summary>
        /// <param name="targetPath"></param>
        /// <returns></returns>
        private CommonResult VaildMergeFile(string targetPath)
        {
            var clientFileName = Request.Form["filename"];


            // 文件字节总数
            var fileTotalSize = Request.Form["fileTotalSize"];

            var targetFile      = new FileInfo(targetPath);
            var streamTotalSize = targetFile.Length;

            if (streamTotalSize != fileTotalSize)
            {
                // 删除本地错误文件
                System.IO.File.Delete(targetPath);
                var errorResult = JResult.Error("[" + clientFileName + "]文件上传时发生损坏,请重新上传");

                #region 记录日志

                //BzfLogger.Log(new SysLog("切片上传-出错-数字档案编码:" + rentDoccode + " 数字档案详情编号: " + rentdoctbDetailId + "  错误信息见详情",
                //        "WebAPP.Api.Flow.RentDocController", errorResult,
                //        "请求路径:" + Request.Url.AbsolutePath));

                #endregion
                return(errorResult);
            }

            // 3.判断上传完的最终的文件是否跟客户端大小一致,只是双保险
            if (fileTotalSize != streamTotalSize)
            {
                var errorResult = JResult.Error("[" + clientFileName + "],文件大小跟上传文件的大小不匹配");
                //HMSLogger.Log(new SysLog("合并-出错-文件大小不一致-见错误详情", "WebAPP.Api.Flow.RentDocController",
                //   errorResult, "请求路径:" + Request.Url.AbsolutePath));

                return(errorResult);
            }

            // 3.1 MD5对文件进行唯一验证
            var identifier = Request.Form["md5"];
            var fileMD5    = GetMD5HashFromFile(targetPath);
            if (!fileMD5.Equals(identifier))
            {
                // 删除本地错误文件
                System.IO.File.Delete(targetPath);
                var errMsg      = "[" + clientFileName + "],文件MD5值不对等";
                var errorResult = JResult.Error(errMsg);
                // BzfLogger.Log(new SysLog(errMsg, "WebAPP.Api.Flow.RentDocController",
                //errorResult, "请求路径:" + Request.Url.AbsolutePath));
                return(errorResult);
            }
            return(JResult.Success());
        }
Beispiel #5
0
        public JsonResult GetMaxChunk(string md5, string ext)
        {
            try
            {
                var reult = JResult.Success();

                // 检测文件夹是否存在,不存在则创建
                var userPath = GetPath();
                if (!Directory.Exists(userPath))
                {
                    DicCreate(userPath);
                }

                var md5Folder = getFileMD5Folder();
                if (!Directory.Exists(md5Folder))
                {
                    DicCreate(md5Folder);
                    return(Json(reult, JsonRequestBehavior.AllowGet));
                }

                var    fileName   = md5 + "." + ext;
                string targetPath = Path.Combine(md5Folder, fileName);
                // 文件已经存在,则可能存在问题,直接删除,重新上传
                if (System.IO.File.Exists(targetPath))
                {
                    System.IO.File.Delete(targetPath);
                    return(Json(reult, JsonRequestBehavior.AllowGet));
                }

                DirectoryInfo dicInfo = new DirectoryInfo(md5Folder);
                var           files   = dicInfo.GetFiles();
                var           chunk   = files.Count();
                if (chunk > 1)
                {
                    //当文件上传中时,页面刷新,上传中断,这时最后一个保存的块的大小可能会有异常,所以这里直接删除最后一个块文件
                    reult.Data = (chunk - 1);
                    return(Json(reult, JsonRequestBehavior.AllowGet));
                }

                return(Json(reult, JsonRequestBehavior.AllowGet));
            }
            catch (Exception ex)
            {
                var errMsg = ex.Message;
                return(Json(JResult.Error(errMsg), JsonRequestBehavior.AllowGet));
            }
        }
Beispiel #6
0
        /// <summary>
        /// 文件上传后调用自有业务
        /// </summary>
        /// <param name="targetPath"></param>
        /// <returns>返回文件对象</returns>
        private CommResult OwnBusiness(string targetPath)
        {
            var fileResult = JResult.Success();

            var filePath = _hostingEnvironment.ContentRootPath + "\\Files\\";

            if (!Directory.Exists(filePath))
            {
                DicCreate(filePath);
            }

            // 移动文件
            var file        = new FileInfo(targetPath);
            var newFilePath = filePath + Request.Form["filename"];

            if (System.IO.File.Exists(newFilePath))
            {
                System.IO.File.Delete(newFilePath);
            }
            file.MoveTo(newFilePath);

            return(fileResult);
        }
Beispiel #7
0
        public JsonResult GetMaxChunk(string md5, string ext)
        {
            try
            {
                var result = JResult.Success();

                // 检测文件夹是否存在,不存在则创建
                var userPath = GetPath();
                if (!Directory.Exists(userPath))
                {
                    DicCreate(userPath);
                }

                var md5Folder = GetFileMd5Folder(md5);
                if (!Directory.Exists(md5Folder))
                {
                    DicCreate(md5Folder);
                    return(Json(result));
                }

                var    fileName   = md5 + "." + ext;
                string targetPath = Path.Combine(md5Folder, fileName);
                // 文件已经存在,则可能存在问题,直接删除,重新上传
                if (System.IO.File.Exists(targetPath))
                {
                    System.IO.File.Delete(targetPath);
                    return(Json(result));
                }

                var dicInfo = new DirectoryInfo(md5Folder);
                var files   = dicInfo.GetFiles();
                var chunk   = files.Count();
                if (chunk > 1)
                {
                    #region 计算切片中途是否有缺失

                    /*   var returnMax = 0;
                     * var fileIntList = files.Select(x => Convert.ToInt32(x.Name)).OrderBy(x => x).ToList();
                     * if (fileIntList == null || fileIntList.Count == 0)
                     *     return Json(JResult.Success(), JsonRequestBehavior.AllowGet);
                     * var maxFileInt = fileIntList.Max();
                     * var minFileInt = fileIntList.Min();
                     * if (minFileInt != 1)
                     *     return Json(JResult.Success());
                     * foreach (var item in fileIntList)
                     * {
                     *     var nextFile = item + 1;
                     *     if (maxFileInt == nextFile)
                     *     {
                     *         returnMax = maxFileInt;
                     *         break;
                     *     }
                     *     if (!fileIntList.Where(x => x == nextFile).Any())
                     *     {
                     *         returnMax = item;
                     *         break;
                     *     }
                     * }*/

                    #endregion
                    //当文件上传中时,页面刷新,上传中断,这时最后一个保存的块的大小可能会有异常,所以这里直接删除最后一个块文件
                    result.Data = (chunk - 1);
                    return(Json(result));
                }

                return(Json(result));
            }
            catch (Exception ex)
            {
                var errMsg = ex.Message;
                return(Json(JResult.Error(errMsg)));
            }
        }
Beispiel #8
0
        /// <summary>
        /// 文件分块上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <param name="md5">文件md5 值</param>
        /// <param name="chunk">当前分片在上传分片中的顺序(从0开始)</param>
        /// <param name="chunks">最大片数</param>
        /// <returns></returns>
        public async Task <JsonResult> ChunkUpload(IFormFile file, string md5, int?chunk, int chunks = 0)
        {
            try
            {
                var result    = JResult.Success();
                var md5Folder = GetFileMd5Folder(md5);
                var filePath  = ""; // 要保存的文件路径

                // 存在分片参数,并且,最大的片数大于1片时
                if (chunk.HasValue && chunks > 1)
                {
                    var uploadNumsOfLoop = 10;
                    // 是10的倍数就休眠几秒(数据库设置的秒数)
                    if (chunk % uploadNumsOfLoop == 0)
                    {
                        var timesOfLoop = 10;   //休眠毫秒,可从数据库取值
                        Thread.Sleep(timesOfLoop);
                    }
                    //建立临时传输文件夹
                    if (!Directory.Exists(md5Folder))
                    {
                        Directory.CreateDirectory(md5Folder);
                    }

                    filePath    = md5Folder + "/" + chunk;
                    result.Code = chunk.Value;
                    if (chunks == chunk)
                    {
                        result.Message = "chunked";
                    }
                }
                else
                {
                    var fileName = file?.FileName;
                    if (string.IsNullOrEmpty(fileName))
                    {
                        var fileNameQuery = Request.Query.FirstOrDefault(t => t.Key == "name");
                        fileName = fileNameQuery.Value.FirstOrDefault();
                    }

                    //没有分片直接保存
                    filePath       = md5Folder + Path.GetExtension(fileName);
                    result.Message = "chunked";
                }

                // 写入文件
                using (var addFile = new FileStream(filePath, FileMode.OpenOrCreate))
                {
                    if (file != null)
                    {
                        await file.CopyToAsync(addFile);
                    }
                    else
                    {
                        await Request.Body.CopyToAsync(addFile);
                    }
                }

                return(Json(result));
            }
            catch (Exception ex)
            {
                return(Json(JResult.Error(ex.Message)));
            }
        }