namespace Yw { /// /// 文件上传 /// public sealed partial class BIMFaceClient { private const string _normalUploadUrl = @"https://file.bimface.com/upload";//普通文件流上传URL private const string _policyUploadUrl = @"https://file.bimface.com/upload/policy";//文件直传URL /// /// 普通文件上传(不推荐) /// /// 文件全路径 /// 文件名称(必须带后缀) public async Task UploadFileByDirect(string filePath, string fileName = null) { await GetAccessToken(); if (string.IsNullOrEmpty(fileName)) { var fileInfo = new FileInfo(filePath); fileName = fileInfo.Name; } var fileNameString = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(fileName)); var url = $"{_normalUploadUrl}?name={fileNameString}"; var request = (HttpWebRequest)WebRequest.Create(url); request.Method = WebRequestMethods.Http.Put; var header = HeaderHelper.GetHeader(_accessToken); request.Headers.Add(header.Key, header.Value); byte[] bytes; using (FileStream steam = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { bytes = new byte[(int)steam.Length]; steam.Read(bytes, 0, bytes.Length); } request.ContentLength = bytes.Length; request.AllowWriteStreamBuffering = true; using (Stream stream = request.GetRequestStream()) { stream.Write(bytes, 0, bytes.Length); stream.Flush(); } var response = request.GetResponse(); string responsetext = string.Empty; using (Stream stream = response.GetResponseStream()) using (StreamReader reader = new StreamReader(stream)) { responsetext = reader.ReadToEnd(); } var result = JsonHelper.Json2Object(responsetext); result.TryThrowException(); return result.Data; } /// /// 文件直传(推荐) /// /// 文件全路径 /// 文件名称(必须带后缀) public async Task UploadFileByPolicy(string filePath, string fileName = null) { await GetAccessToken(); if (string.IsNullOrEmpty(fileName)) { var fileInfo = new FileInfo(filePath); fileName = fileInfo.Name; } var policyResult = await GetUploadFilePolicyAsync(fileName); return await Task.Run(() => { string boundary = "----" + DateTime.Now.Ticks.ToString("x");// 边界符 byte[] beginBoundaryBytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n"); // 边界符开始。【☆】右侧必须要有 \r\n 。 byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); // 边界符结束。【☆】两侧必须要有 --\r\n 。 var textFormTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n" + "{1}\r\n";//文本模板 var fileFormTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + "Content-Type: application/octet-stream\r\n\r\n";//文件模板 var dic = new Dictionary(); dic.Add("name", fileName); dic.Add("key", policyResult.ObjectKey); dic.Add("policy", policyResult.Policy); dic.Add("OSSAccessKeyId", policyResult.AccessId); dic.Add("success_action_status", "200"); dic.Add("callback", policyResult.CallbackBody); dic.Add("signature", policyResult.Signature); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(policyResult.Host); request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary); request.Method = WebRequestMethods.Http.Post; request.AllowWriteStreamBuffering = false; //request.KeepAlive = true; request.Timeout = -1; long contentLength = 0; var textBytesList = dic.Select(x => { var textFormItem = string.Format(textFormTemplate, x.Key, x.Value); byte[] textFormItemBytes = Encoding.UTF8.GetBytes(textFormItem); contentLength += beginBoundaryBytes.Length; contentLength += textFormItemBytes.Length; return textFormItemBytes; }).ToList(); var fileFormItem = string.Format(fileFormTemplate, "file", fileName); byte[] fileFormItemBytes = Encoding.UTF8.GetBytes(fileFormItem); contentLength += beginBoundaryBytes.Length; contentLength += fileFormItemBytes.Length; var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); contentLength += fileStream.Length; contentLength += endBoundaryBytes.Length; request.ContentLength = contentLength; var requestStream = request.GetRequestStream(); textBytesList.ForEach(x => { requestStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); requestStream.Write(x, 0, x.Length); }); requestStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); requestStream.Write(fileFormItemBytes, 0, fileFormItemBytes.Length); //每次上传4M byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))]; int bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { requestStream.Write(buffer, 0, bytesRead); } requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); fileStream.Close(); requestStream.Close(); var response = request.GetResponse(); string responsetext = string.Empty; using (Stream stream = response.GetResponseStream()) using (StreamReader reader = new StreamReader(stream)) { responsetext = reader.ReadToEnd(); } var result = JsonHelper.Json2Object(responsetext); result.TryThrowException(); return result.Data; }); } /// /// 文件直传 Ex(推荐) /// public async Task UploadFileExByPolicy(string filePath, string fileName = null) { var response = await UploadFileByPolicy(filePath, fileName); if (response.Status != Constants.Success) { return 0; } return response.FileId.Value; } //获取文件直传Policy private async Task GetUploadFilePolicyAsync(string fileName) { var fileNameString = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(fileName)); var url = $"{_policyUploadUrl}?name={fileNameString}"; var request = new FlurlRequest(url); var header = HeaderHelper.GetHeader(_accessToken); request.WithHeader(header.Key, header.Value); var response = await request.GetAsync(); var jsonString = await response.GetStringAsync(); var result = JsonHelper.Json2Object(jsonString); result.TryThrowException(); return result.Data; } } }