/// <summary>处理单文件上传</summary> private async Task HandleSingleAsync(ServerUploadRequest request, UploadResult result, List <string> files) { var uploadMD5 = request.Md5?.FirstOrDefault(); var doc = await BuildNew(request, uploadMD5); files.Add(doc.Utf8FileId ?? doc.FileId); }
/// <summary>转换编码</summary> private async Task <string> ConvertCharSetAsync(TDocument doc, ServerUploadRequest request) { if (request.CharSet.IsNullOrEmpty()) { return(null); } if (request.FileName.GetMediaTypeFromFile().IsStream()) { return(null); } var utf8 = Encoding.UTF8; if (request.CharSet.Equals(utf8.WebName, StringComparison.OrdinalIgnoreCase)) { return(doc.FileId); } var newFileDoc = BuildNew(null, request.FileName, utf8.WebName); var content = File.ReadAllText(request.ServerFile, Encoding.GetEncoding(request.CharSet)); var newFile = this.UploadPath + newFileDoc.RelativePath; File.WriteAllText(newFile, content, utf8); newFileDoc.Md5 = BuildMD5(newFile, null); newFileDoc.Utf8FileId = newFileDoc.FileId; await this.UploadFilesCollection.InsertOneAsync(newFileDoc); return(newFileDoc.FileId); }
/// <summary>处理秒传或无文件上传</summary> private async Task HandleNoneAsync(ServerUploadRequest request, UploadResult result, List <string> files) { if (request.Md5.IsNullOrEmpty()) { return; } var md5s = request.Md5.Select(e => e.ToUpperInvariant()).ToArray(); var filter = Builders <TDocument> .Filter.In(f => f.Md5, md5s); using (var cursor = await this.UploadFilesCollection.FindAsync(filter)) { var docs = await cursor.ToListAsync(); foreach (var md5 in md5s) { var doc = docs.FirstOrDefault(e => e.Md5 == md5); if (doc == null) { files.Add(null); continue; } if (request.CharSet.IsNullOrEmpty() || (md5s.Length == 1 && request.FileName.IsNullOrEmpty())) { files.Add(doc.FileId); continue; } await CheckCharSetAsync(md5s.Length > 1, doc, request); files.Add(doc.Utf8FileId ?? doc.FileId); } } }
/// <summary>离线上传</summary> public async Task <TDocument> OfflineUploadAsync(string sourceFile) { var request = new ServerUploadRequest(); request.RelativePath = sourceFile.NormalizeRelativePath(); request.FileName = Path.GetFileName(request.RelativePath); request.ServerFile = this.UploadPath + request.RelativePath; return(await BuildNew(request, null)); }
/// <summary>生成新文档</summary> private async Task <TDocument> BuildNew(ServerUploadRequest request, string uploadMD5) { var doc = BuildNew(request.RelativePath, request.FileName, request.CharSet); doc.Md5 = BuildMD5(request.ServerFile, uploadMD5); doc.Utf8FileId = await ConvertCharSetAsync(doc, request); if (request.RelativePath.IsNullOrEmpty()) { var docFile = this.UploadPath + doc.RelativePath; File.Move(request.ServerFile, docFile); } await this.UploadFilesCollection.InsertOneAsync(doc); return(doc); }
/// <summary>检查编码</summary> private async Task CheckCharSetAsync(bool uploadManyFile, TDocument doc, ServerUploadRequest request) { if (!uploadManyFile) { var fileFormat = request.FileName.GetExtension().GetFileFormat(); if (fileFormat.IsStream) { doc.Utf8FileId = null; return; } } var docContentType = MediaTypeHeaderValue.Parse(doc.ContentType); var newFileDoc = doc; if (request.CharSet.Equals(docContentType.CharSet, StringComparison.OrdinalIgnoreCase)) { if (doc.Utf8FileId != null) { return; } } var utf8 = Encoding.UTF8; if (!utf8.WebName.Equals(request.CharSet, StringComparison.OrdinalIgnoreCase)) { newFileDoc = BuildNew(null, doc.FileName, utf8.WebName); var file = this.UploadPath + doc.RelativePath; var content = File.ReadAllText(file, Encoding.GetEncoding(request.CharSet)); var newFile = this.UploadPath + newFileDoc.RelativePath; File.WriteAllText(newFile, content, utf8); newFileDoc.Utf8FileId = newFileDoc.FileId; newFileDoc.Md5 = BuildMD5(newFile, null); await this.UploadFilesCollection.InsertOneAsync(newFileDoc); } docContentType.CharSet = request.CharSet; var newContentType = docContentType.ToString(); var filter = Builders <TDocument> .Filter.Eq(f => f.FileId, doc.FileId); var update = Builders <TDocument> .Update .Set(u => u.Utf8FileId, newFileDoc.FileId) .Set(u => u.ContentType, newContentType); await this.UploadFilesCollection.UpdateOneAsync(filter, update); doc.Utf8FileId = newFileDoc.FileId; doc.ContentType = newContentType; }
/// <summary>处理分片文件上传</summary> private async Task HandleChunkAsync(ServerUploadRequest request, UploadResult result, List <string> files) { if (request.Chunk < 0 || request.Chunks < 1 || request.Chunk > request.Chunks) { ExceptionCodes.ParameterParsingFailed.ThrowUserFriendly("参数无效!", "分片参数无效!"); } var uploadMD5 = request.Md5?.FirstOrDefault(); result.Chunk = request.Chunk; if (request.Chunk < request.Chunks) { if (request.ServerFile.IsNullOrEmpty()) { ExceptionCodes.MissingParameterValue.ThrowUserFriendly("参数无效!", "分片上传时流不存在!"); } //VerifyMD5(request.ServerFile, uploadMD5); var chunkFile = GetNewChunkFile(request, request.Chunk); File.Move(request.ServerFile, chunkFile); } else { #region 合并分片文件 var mergeFile = GetNewMergeFile(request); var chunkFiles = new List <string>(); using (var mergeStream = new FileStream(mergeFile, FileMode.Create, FileAccess.Write)) { for (var i = 0; i < request.Chunks; i++) { var chunkFile = GetNewChunkFile(request, i); using (var chunkStream = new FileStream(chunkFile, FileMode.Open, FileAccess.Read)) { await chunkStream.CopyToAsync(mergeStream); } chunkFiles.Add(chunkFile); } } request.ServerFile = mergeFile; var doc = await BuildNew(request, uploadMD5); files.Add(doc.Utf8FileId ?? doc.FileId); chunkFiles.ForEach(File.Delete); #endregion } }
public async Task <UploadResult> Upload(UploadRequest request) { var userSession = GetSession(); ServerUploadRequest request2 = new ServerUploadRequest(request); request2.UserId = userSession?.Id; if (request2.Chunk < request2.Chunks || request2.Guid.IsEmpty()) { IFormFile file = Request.Form.Files[0]; request2.FileName = file.FileName; string serverFile = Path.Combine(_fileService.TempPath, Guid.NewGuid().ToString()); FileStream fs = System.IO.File.Create(serverFile); file.CopyTo(fs); fs.Close(); request2.ServerFile = serverFile; } return(await _fileService.UploadAsync(request2)); }
/// <summary>处理文件上传</summary> public async Task <UploadResult> UploadAsync(ServerUploadRequest request) { var result = new UploadResult(); var files = new List <string>(); if (request.Guid.IsNullOrEmpty()) { if (request.ServerFile.IsNullOrEmpty()) { await HandleNoneAsync(request, result, files); } else { await HandleSingleAsync(request, result, files); } } else { await HandleChunkAsync(request, result, files); } result.TempFileIds = files.ToArray(); return(result); }
/// <summary>上传文件,支持秒传和分片</summary> public async Task <UploadResult> UploadAsync(ServerUploadRequest request) { return(await UploadFileHandler.UploadAsync(request)); }
/// <summary>上传文件,支持秒传和分片</summary> public UploadResult Upload(ServerUploadRequest request) { return(Task.Run(() => UploadAsync(request)).Result); }
/// <summary>载入上传的第一个文件流</summary> protected async Task <ServerUploadRequest> LoadFileStreamFirstOrDefault(UploadRequest request, string uploadPath) { var request2 = new ServerUploadRequest(request); var httpContent = this.Request.Content; NameValueCollection formData = null; if (httpContent.IsFormData()) { formData = await httpContent.ReadAsFormDataAsync(); } else if (httpContent.Headers.ContentType.MediaType.IsJsonMedia()) { var content = await httpContent.ReadAsStringAsync(); request2 = content.JsonTo <ServerUploadRequest>(); } else if (httpContent.IsMimeMultipartContent()) { var provider = await httpContent.ReadAsMultipartAsync(new MultipartFormDataStreamProvider(uploadPath)); var fileData = provider.FileData.FirstOrDefault(); if (fileData != null) { request2.FileName = fileData.Headers.ContentDisposition.FileName.Divest(); request2.CharSet = fileData.Headers.ContentType.CharSet; request2.ServerFile = fileData.LocalFileName; } formData = provider.FormData; } if (formData != null) { string formDataValue = null; if (request2.FileName.IsNullOrEmpty()) { request2.FileName = formData[nameof(request2.FileName)]; } if (request2.CharSet.IsNullOrEmpty()) { request2.CharSet = formData[nameof(request2.CharSet)]; } if (request2.Md5.IsNullOrEmpty()) { formDataValue = formData[nameof(request2.Md5)]; if (formDataValue != null) { request2.Md5 = formDataValue.Split(','); } } if (request2.Guid.IsNullOrEmpty()) { request2.Guid = formData[nameof(request2.Guid)]; } if (request2.Chunk < 0) { formDataValue = formData[nameof(request2.Chunk)]; if (formDataValue != null) { request2.Chunk = formDataValue.ToInt32(); } } if (request2.Chunks < 0) { formDataValue = formData[nameof(request2.Chunks)]; if (formDataValue != null) { request2.Chunks = formDataValue.ToInt32(); } } } return(request2); }
/// <summary>获得分片合并文件路径</summary> private string GetNewMergeFile(ServerUploadRequest request) { var ext = Path.GetExtension(request.FileName); return($@"{this.TempPath}\{request.Guid}{ext}"); }
/// <summary>获得新分片文件路径</summary> private string GetNewChunkFile(ServerUploadRequest request, int chunk) { var ext = Path.GetExtension(request.FileName); return($@"{this.TempPath}\{request.Guid}_PART_{chunk.ToString()}{ext}"); }