public ResumeBlocker( ManualResetEvent doneEvent, byte[] blockBuffer, long blockIndex, string uploadToken, PutExtra putExtra, ResumeInfo resumeInfo, Dictionary <long, HttpResult> blockMakeResults, object progressLock, Dictionary <string, long> uploadedBytesDict, long fileSize) { DoneEvent = doneEvent; BlockBuffer = blockBuffer; BlockIndex = blockIndex; UploadToken = uploadToken; PutExtra = putExtra; ResumeInfo = resumeInfo; BlockMakeResults = blockMakeResults; ProgressLock = progressLock; UploadedBytesDict = uploadedBytesDict; FileSize = fileSize; }
/// <summary> /// 上传数据流 /// </summary> /// <param name="stream">(确定长度的)数据流</param> /// <param name="key">要保存的key</param> /// <param name="token">上传凭证</param> /// <param name="putExtra">上传可选设置</param> /// <returns>上传数据流后的返回结果</returns> public async Task <HttpResult> UploadStream(Stream stream, string key, string token, PutExtra putExtra) { if (putExtra == null) { putExtra = new PutExtra(); } if (string.IsNullOrEmpty(putExtra.MimeType)) { putExtra.MimeType = ContentType.APPLICATION_OCTET_STREAM; } if (putExtra.ProgressHandler == null) { putExtra.ProgressHandler = DefaultUploadProgressHandler; } if (putExtra.UploadController == null) { putExtra.UploadController = DefaultUploadController; } var fileName = key; if (string.IsNullOrEmpty(key)) { fileName = "fname_temp"; } var result = new HttpResult(); try { var boundary = HttpManager.CreateFormDataBoundary(); var content = new MultipartFormDataContent(boundary); var length = stream.Length; putExtra.ProgressHandler(0, length); // Key if (!string.IsNullOrEmpty(key)) { content.Add(new StringContent(key), "key"); } // Token content.Add(new StringContent(token), "token"); // Other params if (putExtra.Params != null) { foreach (var param in putExtra.Params) { content.Add(new StringContent(param.Value), param.Key); } } // Reuse stream if (!stream.CanSeek) { var ms = new MemoryStream((int)stream.Length); stream.CopyTo(ms); stream.Dispose(); stream = ms; } // CRC32 var crc32 = Crc32.CheckSumStream(stream); stream.Seek(0, SeekOrigin.Begin); content.Add(new StringContent(crc32.ToString()), "crc32"); // Primary content var part = new StreamContent(stream); part.Headers.ContentType = MediaTypeHeaderValue.Parse(putExtra.MimeType); content.Add(part, "file", fileName); // Get upload host var ak = UpToken.GetAccessKeyFromUpToken(token); var bucket = UpToken.GetBucketFromUpToken(token); if (ak == null || bucket == null) { return(HttpResult.InvalidToken); } var uploadHost = await _config.UpHost(ak, bucket); // TODO: Real progress putExtra.ProgressHandler(length / 5, length); result = await _httpManager.PostAsync(uploadHost, content, boundary); putExtra.ProgressHandler(length, length); if (result.Code == (int)HttpCode.OK) { result.RefText += $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [FormUpload] Uploaded: #STREAM# ==> \"{key}\"\n"; } else { result.RefText += $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [FormUpload] Failed: code = {result.Code}, text = {result.Text}\n"; } } catch (Exception ex) { var sb = new StringBuilder(); sb.Append($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [FormUpload] Error: "); var e = ex; while (e != null) { sb.Append(e.Message + " "); e = e.InnerException; } sb.AppendLine(); if (ex is QiniuException qex) { result.Code = qex.HttpResult.Code; result.RefCode = qex.HttpResult.Code; result.Text = qex.HttpResult.Text; result.RefText += sb.ToString(); } else { result.RefCode = (int)HttpCode.USER_UNDEF; result.RefText += sb.ToString(); } } return(result); }
/// <summary> /// 上传数据 /// </summary> /// <param name="data">待上传的数据</param> /// <param name="key">要保存的key</param> /// <param name="token">上传凭证</param> /// <param name="extra">上传可选设置</param> /// <returns>上传数据后的返回结果</returns> public Task <HttpResult> UploadData(byte[] data, string key, string token, PutExtra extra) { var stream = new MemoryStream(data); return(UploadStream(stream, key, token, extra)); }
/// <summary> /// 上传文件 - 可附加自定义参数 /// </summary> /// <param name="localFile">待上传的本地文件</param> /// <param name="key">要保存的目标文件名称</param> /// <param name="token">上传凭证</param> /// <param name="extra">上传可选设置</param> /// <returns>上传文件后的返回结果</returns> public async Task <HttpResult> UploadFile(string localFile, string key, string token, PutExtra extra) { try { var fs = new FileStream(localFile, FileMode.Open); return(await UploadStream(fs, key, token, extra)); } catch (Exception ex) { var ret = HttpResult.InvalidFile; ret.RefText = ex.Message; return(ret); } }
/// <summary> /// 上传文件数据流,根据文件大小以及设置的阈值(用户初始化UploadManager时可指定该值)自动选择: /// 若文件大小超过设定阈值,使用ResumableUploader,否则使用FormUploader /// </summary> /// <param name="stream">待上传的数据流</param> /// <param name="key">要保存的文件名称</param> /// <param name="token">上传凭证</param> /// <param name="extra">上传可选设置</param> /// <returns>上传文件后的返回结果</returns> public Task <HttpResult> UploadStream(Stream stream, string key, string token, PutExtra extra) { if (stream.Length > _config.PutThreshold) { return(_resumableUploader.UploadStream(stream, key, token, extra)); } return(_formUploader.UploadStream(stream, key, token, extra)); }
/// <summary> /// 上传文件,根据文件大小以及设置的阈值(用户初始化UploadManager时可指定该值)自动选择: /// 若文件大小超过设定阈值,使用ResumableUploader,否则使用FormUploader /// </summary> /// <param name="localFile">本地待上传的文件名</param> /// <param name="key">要保存的文件名称</param> /// <param name="token">上传凭证</param> /// <param name="extra">上传可选设置</param> /// <returns>上传文件后的返回结果</returns> public Task <HttpResult> UploadFile(string localFile, string key, string token, PutExtra extra) { var fi = new System.IO.FileInfo(localFile); if (fi.Length > _config.PutThreshold) { return(_resumableUploader.UploadFile(localFile, key, token, extra)); } return(_formUploader.UploadFile(localFile, key, token, extra)); }
/// <summary> /// 上传数据 /// </summary> /// <param name="data">待上传的数据</param> /// <param name="key">要保存的文件名称</param> /// <param name="token">上传凭证</param> /// <param name="extra">上传可选设置</param> /// <returns>上传文件后的返回结果</returns> public Task <HttpResult> UploadData(byte[] data, string key, string token, PutExtra extra) { return(_formUploader.UploadData(data, key, token, extra)); }