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

                    MergeDiskFile(sourcePath, targetFilePath);
                }

                var valid = VaildMergeFile(targetFilePath);
                DeleteFolder(sourcePath);
                if (!valid.Result)
                {
                    return(valid);
                }
                var fileResult = OwnBusiness(targetFilePath);
                return(JsonResultDto.Success(fileResult));
            }
            catch (Exception ex)
            {
                return(JsonResultDto.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(JsonResultDto.Success());
            }
            catch (Exception ex)
            {
                // 删除本地错误文件
                System.IO.File.Delete(targetPath);
                return(JsonResultDto.Error(ex.Message));
            }
        }
Beispiel #3
0
        /// <summary>
        /// 文件上传后调用自有业务
        /// </summary>
        /// <param name="targetPath"></param>
        /// <returns>返回文件对象</returns>
        private CommResult OwnBusiness(string targetPath)
        {
            var fileResult = JsonResultDto.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 #4
0
        public CommResult GetMaxChunk(string md5, string ext)
        {
            try
            {
                var result = JsonResultDto.Success();

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

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

                var    fileName   = md5 + "." + ext;
                string targetPath = Path.Combine(md5Folder, fileName);
                // 文件已经存在,则可能存在问题,直接删除,重新上传
                if (System.IO.File.Exists(targetPath))
                {
                    System.IO.File.Delete(targetPath);
                    return(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.Any())
                    {
                        return(JsonResultDto.Success());
                    }
                    var maxFileInt = fileIntList.Max();
                    var minFileInt = fileIntList.Min();
                    if (minFileInt != 1)
                    {
                        return(JsonResultDto.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(result);
                }

                return(result);
            }
            catch (Exception ex)
            {
                var errMsg = ex.Message;
                return(JsonResultDto.Error(errMsg));
            }
        }
Beispiel #5
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 <CommResult> ChunkUpload(IFormFile file, string md5, int?chunk, int chunks = 0)
        {
            try
            {
                var result    = JsonResultDto.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(result);
            }
            catch (Exception ex)
            {
                return(JsonResultDto.Error(ex.Message));
            }
        }