/// <summary> /// 根据已上传的所有分片数据创建文件 /// </summary> /// <param name="uploadBatch">分片上传的会话 ID</param> /// <param name="size">文件大小</param> /// <param name="key">要保存的文件名</param> /// <param name="contexts">所有数据块的Context</param> /// <param name="uploadToken">上传凭证</param> /// <param name="putExtra">用户指定的额外参数</param> /// <returns>此操作执行后的返回结果</returns> private HttpResult MakeFile(long size, string key, string[] contexts, string uploadToken, string uploadUrl, string uploadBatch, PutExtra putExtra = null) { StringBuilder url = new StringBuilder(); url.Append(uploadUrl + "/mkfile/" + size.ToString()); if (null != putExtra && null != putExtra.Params && putExtra.Params.Count > 0) { foreach (KeyValuePair <string, string> p in putExtra.Params) { if (p.Key.StartsWith("x:")) { url.Append("/" + p.Key + "/" + Base64.UrlSafeBase64Encode(p.Value)); } } } StringBuilder ctxList = new StringBuilder(); foreach (string ctx in contexts) { ctxList.Append(ctx + ","); } Dictionary <string, string> customHeaders = new Dictionary <string, string> { { "UploadBatch", uploadBatch } }; if (!string.IsNullOrEmpty(key)) { customHeaders.Add("Key", Base64.UrlSafeBase64Encode(key)); } if (null != putExtra && !string.IsNullOrEmpty(putExtra.MimeType)) { customHeaders.Add("MimeType", putExtra.MimeType); } if (null != putExtra && 0 <= putExtra.Deadline) { customHeaders.Add("Deadline", putExtra.Deadline.ToString()); } return(httpManager.Post(url.ToString(), Encoding.UTF8.GetBytes(ctxList.ToString(0, ctxList.Length - 1)), uploadToken, "text/plain;charset=UTF-8", customHeaders)); }
/// <summary> /// 上传本地文件,可能抛异常 /// </summary> /// <param name="localFilename">本地文件名</param> /// <param name="putPolicy">上传策略数据,JSON 字符串</param> /// <param name="key">可选,要保存的key</param> /// <param name="extra">上传可选设置</param> /// <returns>上传数据流后的返回结果</returns> private HttpResult UploadFile(string localFilename, string token, string uploadUrl, string key = null, PutExtra putExtra = null) { using (FileStream fs = new FileStream(localFilename, FileMode.Open)) { return(UploadStream(fs, token, uploadUrl, key, putExtra)); } }
/// <summary> /// 上传数据 /// </summary> /// <param name="data">待上传的数据</param> /// <param name="key">可选,要保存的key</param> /// <param name="extra">可选,上传可选设置</param> /// <returns>上传数据后的返回结果</returns> private HttpResult UploadData(byte[] data, string token, string uploadUrl, string key = null, PutExtra putExtra = null) { if (putExtra == null) { putExtra = new PutExtra(); } string filename = key; if (string.IsNullOrEmpty(key)) { filename = "uploading.tmp"; } string boundary = HttpManager.CreateFormDataBoundary(); StringBuilder bodyBuilder = new StringBuilder(); bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"token\"\r\n\r\n" + token + "\r\n"); if (null != putExtra.Params && putExtra.Params.Count > 0) { foreach (KeyValuePair <string, string> p in putExtra.Params) { if (p.Key.StartsWith("x:")) { bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"" + p.Key + "\"\r\n\r\n" + p.Value + "\r\n"); } } } // write key if (null != key) { bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"key\"\r\n\r\n" + key + "\r\n"); } // write mime type if (!string.IsNullOrEmpty(putExtra.MimeType)) { bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"mimeType\"\r\n\r\n" + putExtra.MimeType + "\r\n"); } // write deadline if (-1 != putExtra.Deadline) { bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"deadline\"\r\n\r\n" + putExtra.Deadline.ToString() + "\r\n"); } // write filename bodyBuilder.Append("--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"" + filename + "\"\r\nContent-Type: application/octet-stream\r\n\r\n"); // write file data StringBuilder bodyEnd = new StringBuilder(); bodyEnd.Append("\r\n--" + boundary + "--\r\n"); byte[] partHead = Encoding.UTF8.GetBytes(bodyBuilder.ToString()); byte[] partTail = Encoding.UTF8.GetBytes(bodyEnd.ToString()); // 允许空内容 int dataLength = 0; if (null != data) { dataLength = data.Length; } byte[] body = new byte[partHead.Length + dataLength + partTail.Length]; //Array.Copy(partHead, 0, body, 0, partHead.Length); // Buffer.BlockCopy 比 Array.Copy 简单,所以更快。 Buffer.BlockCopy(partHead, 0, body, 0, partHead.Length); if (null == data) { Buffer.BlockCopy(partTail, 0, body, partHead.Length, partTail.Length); } else { Buffer.BlockCopy(data, 0, body, partHead.Length, data.Length); Buffer.BlockCopy(partTail, 0, body, partHead.Length + data.Length, partTail.Length); } string url = uploadUrl + "/file/upload"; HttpResult result = httpManager.PostMultipart(url, body, boundary); return(result); }
/// <summary> /// 上传数据流 /// </summary> /// <param name="stream">(确定长度的)数据流</param> /// <param name="putPolicy">上传策略数据,JSON 字符串</param> /// <param name="key">可选,要保存的key</param> /// <param name="extra">上传可选设置</param> /// <returns>上传数据流后的返回结果</returns> private HttpResult UploadStream(Stream stream, string token, string uploadUrl, string key = null, PutExtra putExtra = null) { int bufferSize = 4 * 1024 * 1024; byte[] buffer = new byte[bufferSize]; int bytesRead = 0; using (MemoryStream dataMS = new MemoryStream()) { while ((bytesRead = stream.Read(buffer, 0, bufferSize)) != 0) { dataMS.Write(buffer, 0, bytesRead); } return(UploadData(dataMS.ToArray(), token, uploadUrl, key, putExtra)); } }