async Task <Metadata> LoadFile(string path, string destPath, Action <float> progress, CancellationToken token) { var session = EnsureLoggedIn(); var uri = FormatUri((DropboxService)session.Service, BaseContentUri, "files/{root}{path}", path); var request = session.Service.CreateRequest("GET", uri, session.Account); Response res = await request.GetResponseAsync(token).ConfigureAwait(false); token.ThrowIfCancellationRequested(); var metadataText = res.Headers ["x-dropbox-metadata"]; var metadata = ParseMetadata(JToken.Parse(metadataText)); const int BufferLength = 16 * 1024; using (var state = new LoadFileAsyncState { OutputStream = File.Create(destPath), ResponseStream = res.GetResponseStream(), OnProgress = progress, Metadata = metadata, TotalBytes = Int64.Parse(res.Headers["Content-Length"]), Buffer = new byte [BufferLength], BufferLength = BufferLength }) { try { int readBytes; do { readBytes = await ReadNextChunkAsync(state).ConfigureAwait(false); token.ThrowIfCancellationRequested(); } while (readBytes > 0); return(metadata); } catch { TryDelete(destPath); throw; } } }
async Task <int> ReadNextChunkAsync(LoadFileAsyncState state) { int bytesRead = await Task.Factory.FromAsync <byte[], int, int, int> ( state.ResponseStream.BeginRead, state.ResponseStream.EndRead, state.Buffer, 0, state.BufferLength, null ).ConfigureAwait(false); if (bytesRead > 0) { state.BytesLoaded += bytesRead; if (state.OnProgress != null) { state.OnProgress(((float)state.BytesLoaded) / state.TotalBytes); } state.OutputStream.Write(state.Buffer, 0, bytesRead); } return(bytesRead); }
async Task<int> ReadNextChunkAsync (LoadFileAsyncState state) { int bytesRead = await Task.Factory.FromAsync<byte[], int, int, int> ( state.ResponseStream.BeginRead, state.ResponseStream.EndRead, state.Buffer, 0, state.BufferLength, null ).ConfigureAwait (false); if (bytesRead > 0) { state.BytesLoaded += bytesRead; if (state.OnProgress != null) state.OnProgress (((float) state.BytesLoaded) / state.TotalBytes); state.OutputStream.Write (state.Buffer, 0, bytesRead); } return bytesRead; }
async Task<Metadata> LoadFile (string path, string destPath, Action<float> progress, CancellationToken token) { var session = EnsureLoggedIn (); var uri = FormatUri ((DropboxService) session.Service, BaseContentUri, "files/{root}{path}", path); var request = session.Service.CreateRequest ("GET", uri, session.Account); Response res = await request.GetResponseAsync (token).ConfigureAwait (false); token.ThrowIfCancellationRequested (); var metadataText = res.Headers ["x-dropbox-metadata"]; var metadata = ParseMetadata (JToken.Parse (metadataText)); const int BufferLength = 16 * 1024; using (var state = new LoadFileAsyncState { OutputStream = File.Create (destPath), ResponseStream = res.GetResponseStream (), OnProgress = progress, Metadata = metadata, TotalBytes = Int64.Parse (res.Headers["Content-Length"]), Buffer = new byte [BufferLength], BufferLength = BufferLength }) { try { int readBytes; do { readBytes = await ReadNextChunkAsync (state).ConfigureAwait (false); token.ThrowIfCancellationRequested (); } while (readBytes > 0); return metadata; } catch { TryDelete (destPath); throw; } } }