/// <summary>
        /// 开始上传
        /// </summary>
        /// <param name="upload"></param>
        public async void UploadStart(Upload upload)
        {
            UploadStatus = UploadStatus.Uploading;
            if (upload != null && upload.FileType != (int)FileType.UNKNOWN)
            {
                using (FileStream fileStream = new FileStream(upload.FilePath, FileMode.Open, FileAccess.Read))
                {
                    var buffer         = new byte[CHUNKSIZE];
                    int chunkNumber    = upload.ChunkNumber;
                    int totalSize      = upload.FileSize;
                    int totalChunks    = (int)Math.Ceiling((double)totalSize / CHUNKSIZE);
                    int bytesRead      = 0;
                    int offset         = chunkNumber * CHUNKSIZE;
                    int uploadedLength = offset;
                    fileStream.Seek((long)offset, SeekOrigin.Begin);

                    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        //如果暂停了
                        if (UploadStatus == UploadStatus.Pause)
                        {
                            break;
                        }
                        //开始时间
                        var watch = new Stopwatch();
                        watch.Start();
                        //byte转换
                        var finalBuffer = new byte[bytesRead];
                        Buffer.BlockCopy(buffer, 0, finalBuffer, 0, bytesRead);
                        //上传一个分片
                        var response = await HttpManager.Instance.BreakPointUploadAsync <BreakPointUploadResponse>(
                            new UploadAlbumFileRequest(upload.TargetId, upload.AlbumId, (AlbumType)upload.AlbumType, upload.FileName, (FileType)upload.FileType, upload.Identifier, totalSize, totalChunks, chunkNumber, CHUNKSIZE, bytesRead), finalBuffer
                            );

                        Logger.Log(response.message);
                        //当前分片上传失败(只要不是完成和分片成功都视为失败)
                        if (!response.Ok && response.code != 201)
                        {
                            OnUploadFailure?.Invoke();
                            break;
                        }
                        //上传完成
                        if (response.Ok)
                        {
                            OnUploadCompleted?.Invoke();
                            UploadManager.DeleteUploader(upload);
                            break;
                        }
                        var progress = Convert.ToDouble((uploadedLength / (Double)totalSize) * 100);
                        //当前分片上传成功
                        upload.Progress    = progress;
                        upload.ChunkNumber = chunkNumber;
                        var a = UploadManager.UpdateUploader(upload);
                        chunkNumber++;//文件块序号+1
                        //结束时间
                        watch.Stop();
                        uploadedLength += bytesRead;
                        //速度计算byte/s
                        var speed = CHUNKSIZE * 1000L / watch.ElapsedMilliseconds;
                        //计算剩余时间
                        var time = (totalSize - uploadedLength) / speed;
                        //上传进度通知
                        OnUploadProgressChanged?.Invoke(progress, (int)time, speed / 1024);
                    }
                }
            }
        }
        /// <summary>
        /// Uploads a file to a given path.
        /// </summary>
        /// <param name="fileContents">The file contents.</param>
        /// <param name="fileName">The file name (including extension).</param>
        /// <param name="fileType">The file content type.</param>
        /// <param name="path">The path to upload the file to.</param>
        /// <returns>Either the uploaded file or an error.</returns>
        public Task <Option <CloudFile, Error> > UploadFile(System.IO.Stream fileContents, string fileName, string mimeType, string path) =>
        // TODO: Decide whether to create a new folder if the provided doesn't exist
        GetFolderIdFromPathAsync(path).MapAsync(async parentFolderId =>
        {
            var fileMetadata = new File()
            {
                Name     = fileName,
                Parents  = new[] { parentFolderId },
                MimeType = mimeType
            };

            var uploadRequest = _driveService
                                .Files
                                .Create(fileMetadata, fileContents, fileMetadata.MimeType);

            // Return the id and name fields when finished uploading
            uploadRequest.Fields    = "id,name";
            uploadRequest.ChunkSize = ResumableUpload.MinimumChunkSize;

            uploadRequest.ProgressChanged += progress =>
            {
                switch (progress.Status)
                {
                case UploadStatus.NotStarted:
                    break;

                case UploadStatus.Starting:
                    OnUploadStarting?.Invoke(new UploadStarting {
                        FileName = fileName, DestinationPath = path, FileSizeInBytes = fileContents.Length
                    });
                    break;

                case UploadStatus.Uploading:
                    OnUploadProgressChanged?.Invoke(new UploadProgress {
                        FileName = fileName, BytesSent = progress.BytesSent, TotalBytesToSend = fileContents.Length
                    });
                    break;

                case UploadStatus.Completed:
                    OnUploadSuccessfull?.Invoke(new UploadSuccessResult {
                        FileName = fileName, Path = path
                    });
                    break;

                case UploadStatus.Failed:
                    OnUploadFailure?.Invoke(new UploadFailureResult {
                        FileName = fileName, Path = path, Exception = progress.Exception
                    });
                    break;

                default:
                    break;
                }
            };

            var result = await uploadRequest.UploadAsync();

            var uploadedFile = uploadRequest.ResponseBody;

            return(uploadedFile);
        })
        .MapAsync(async f => ToCloudFile(f));