Esempio n. 1
0
        public virtual async Task AppendFileAsync([FromQuery] VersionFileCreateDto versionFileCreate)
        {
            // 检查文件大小
            var fileSizeLimited = await SettingProvider
                                  .GetAsync(PlatformSettingNames.AppVersion.VersionFileLimitLength, AppVersionConsts.DefaultVersionFileLimitLength);

            if (fileSizeLimited * 1024 * 1024 < versionFileCreate.TotalByte)
            {
                throw new UserFriendlyException(L["UploadFileSizeBeyondLimit", fileSizeLimited]);
            }
            // 采用分块模式上传文件

            // 保存分块到临时目录
            var fileName = versionFileCreate.FileName;
            // 文件扩展名
            var fileExtensionName  = FileHelper.GetExtension(fileName);
            var fileAllowExtension = await SettingProvider
                                     .GetOrNullAsync(PlatformSettingNames.AppVersion.AllowVersionFileExtensions);

            if (fileAllowExtension.IsNullOrWhiteSpace())
            {
                fileAllowExtension = AppVersionConsts.DefaultAllowVersionFileExtensions;
            }
            // 检查文件扩展名
            if (!fileAllowExtension.Split(',').Any(fe => fe.Equals(fileExtensionName, StringComparison.CurrentCultureIgnoreCase)))
            {
                throw new UserFriendlyException(L["NotAllowedFileExtensionName", fileExtensionName]);
            }
            // 当前计算机临时目录
            var tempFilePath = Environment.GetFolderPath(Environment.SpecialFolder.Templates);

            // 以上传的文件名创建一个临时目录
            tempFilePath = Path.Combine(tempFilePath, "lingyun-platform", Path.GetFileNameWithoutExtension(fileName));
            // 以上传的分片索引创建临时文件
            var tempSavedFile = Path.Combine(tempFilePath, $"{versionFileCreate.CurrentByte}.{fileExtensionName}");

            if (!Directory.Exists(tempFilePath))
            {
                // 临时目录不存在则创建
                Directory.CreateDirectory(tempFilePath);
            }
            try
            {
                if (HttpContext.RequestAborted.IsCancellationRequested)
                {
                    // 如果取消请求,删除临时目录
                    Directory.Delete(tempFilePath, true);
                    return;
                }
                // 保存临时文件
                using (var fs = new FileStream(tempSavedFile, FileMode.Create, FileAccess.Write))
                {
                    // 写入当前分片文件
                    await Request.Body.CopyToAsync(fs);
                }

                if (versionFileCreate.CurrentByte == versionFileCreate.TotalByte)
                {
                    // 合并文件
                    var mergeSavedFile = Path.Combine(tempFilePath, $"{fileName}");
                    // 获取并排序所有分片文件
                    var mergeFiles = Directory.GetFiles(tempFilePath).OrderBy(f => f.Length).ThenBy(f => f);
                    // 创建临时合并文件
                    using (var mergeSavedFileStream = new FileStream(mergeSavedFile, FileMode.Create))
                    {
                        foreach (var mergeFile in mergeFiles)
                        {
                            // 读取当前文件字节
                            var mergeFileBytes = await FileHelper.ReadAllBytesAsync(mergeFile);

                            // 写入到合并文件流
                            await mergeSavedFileStream.WriteAsync(mergeFileBytes, 0, mergeFileBytes.Length);

                            // 删除已参与合并的临时文件分片
                            FileHelper.DeleteIfExists(mergeFile);
                        }
                        // 上传最终合并的文件并取得SHA256指纹
                        var fileData = await mergeSavedFileStream.GetAllBytesAsync();

                        versionFileCreate.SHA256 = await _versionFileManager.SaveFileAsync(versionFileCreate.Version,
                                                                                           versionFileCreate.FilePath, versionFileCreate.FileName, versionFileCreate.FileVersion, fileData);
                    }
                    // 添加到版本信息
                    await _versionAppService.AppendFileAsync(versionFileCreate);

                    // 文件保存之后删除临时文件目录
                    Directory.Delete(tempFilePath, true);
                }
            }
            catch
            {
                // 发生异常删除临时文件目录
                Directory.Delete(tempFilePath, true);
                throw;
            }
        }
Esempio n. 2
0
 public virtual async Task AppendFileAsync(VersionFileCreateDto versionFileCreate)
 {
     await _versionManager.AppendFileAsync(versionFileCreate.VersionId,
                                           versionFileCreate.SHA256, versionFileCreate.FileName, versionFileCreate.FileVersion,
                                           versionFileCreate.TotalByte, versionFileCreate.FilePath, versionFileCreate.FileType);
 }