Exemplo n.º 1
0
        public async Task DownloadAsync(Uri address, string directory, string fileName, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            DownloadContext downloadContext = new DownloadContext();

            if (!_uriContexts.TryAdd(address, downloadContext))
            {
                throw new ApplicationException("The url is downloading.");
            }

            try {
                using (cancellationToken.Register(CancelAsync))
                    using (Stream responseStream = await OpenReadTaskAsync(address).ConfigureAwait(false)) {
                        HttpWebResponse response = _uriContexts[address].Response;

                        if (fileName.IsNullOrEmpty())
                        {
                            fileName = response.GetContentDispositionFileName() ??
                                       Path.GetFileName(response.ResponseUri.AbsolutePath) ??
                                       throw new ArgumentException("fileName");
                        }

                        string   fullPath = Path.Combine(directory, fileName);
                        FileMode fileMode = FileMode.Create;
                        FileInfo file     = new FileInfo(fullPath);
                        if (file.Exists)
                        {
                            FileExistsContext fileExistsContext = new FileExistsContext(response.ResponseUri, fullPath)
                            {
                                FileExistsHandling = _defaultFileExistsHandling,
                            };
                            FileExists?.Invoke(this, new EventArgs <FileExistsContext>(fileExistsContext));

                            switch (fileExistsContext.FileExistsHandling)
                            {
                            case FileExistsHandling.Ignore:
                                return;

                            case FileExistsHandling.Resume:
                                if (file.Length >= response.ContentLength)
                                {
                                    return;
                                }

                                fileMode = FileMode.OpenOrCreate;
                                downloadContext.CurrentFileLength = file.Length;
                                break;

                            case FileExistsHandling.Rename:
                                do
                                {
                                    string newFileName = "{0} - New{1}".FormatWith(
                                        Path.GetFileNameWithoutExtension(fullPath), Path.GetExtension(fullPath));
                                    fullPath = Path.Combine(directory, newFileName);
                                    file     = new FileInfo(fullPath);
                                } while (file.Exists);
                                break;
                            }
                        }

                        using (FileStream fileStream = new FileStream(fullPath, fileMode)) {
                            if (downloadContext.CurrentFileLength > 0 && downloadContext.Response.IsRangeSupported())
                            {
                                fileStream.Seek(downloadContext.CurrentFileLength, SeekOrigin.Begin);
                            }

                            await responseStream.CopyToAsync(fileStream).ConfigureAwait(false);

                            await fileStream.FlushAsync().ConfigureAwait(false);
                        }
                    }
            }
            finally {
                _uriContexts.TryRemove(address, out DownloadContext value);
            }
        }