Ejemplo n.º 1
0
        /// <summary>
        /// 下载图片,不在本地缓存文件,直接返回BitmapImage对象
        /// </summary>
        /// <param name="p_path">要下载的文件路径</param>
        /// <returns></returns>
        public static async Task <BitmapImage> GetImage(string p_path)
        {
            if (string.IsNullOrEmpty(p_path))
            {
                return(null);
            }

            // 路径肯定含/
            int index = p_path.LastIndexOf('/');

            if (index <= 0)
            {
                return(null);
            }

            MemoryStream stream = new MemoryStream();
            DownloadInfo info   = new DownloadInfo
            {
                Path      = p_path,
                TgtStream = stream,
            };

            bool suc = false;

            try
            {
                suc = await GetFile(info, CancellationToken.None);

                if (suc)
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    BitmapImage bmp = new BitmapImage();
#if UWP
                    var randomStream = new InMemoryRandomAccessStream();
                    var outputStream = randomStream.GetOutputStreamAt(0);
                    await RandomAccessStream.CopyAsync(stream.AsInputStream(), outputStream);

                    await bmp.SetSourceAsync(randomStream);
#else
                    await bmp.SetSourceAsync(stream);
#endif
                    return(bmp);
                }
            }
            finally
            {
                stream.Close();
            }
            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 下载文件并缓存到本地
        /// </summary>
        /// <param name="p_path">要下载的文件路径,以原有文件名缓存到本地</param>
        /// <returns>false 下载失败,缓存文件已删除</returns>
        public static async Task <bool> GetAndCacheFile(string p_path)
        {
            if (string.IsNullOrEmpty(p_path))
            {
                return(false);
            }

            // 路径肯定含/
            int index = p_path.LastIndexOf('/');

            if (index <= 0)
            {
                return(false);
            }

            string       path   = Path.Combine(Kit.CachePath, p_path.Substring(index + 1));
            FileStream   stream = File.Create(path);
            DownloadInfo info   = new DownloadInfo
            {
                Path      = p_path,
                TgtStream = stream,
            };

            bool suc = false;

            try
            {
                suc = await GetFile(info, CancellationToken.None);
            }
            finally
            {
                stream.Close();
            }

            if (!suc)
            {
                // 未成功,删除缓存文件,避免打开时出错
                try
                {
                    // mono中 FileInfo 的 Exists 状态不同步!
                    if (System.IO.File.Exists(path))
                    {
                        System.IO.File.Delete(path);
                    }
                }
                catch { }
            }
            return(suc);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 执行下载
        /// </summary>
        /// <param name="p_priorThumbnail">是否优先下载缩略图</param>
        /// <param name="p_prompt">是否提示下载失败信息</param>
        /// <returns></returns>
        internal async Task <bool> Download(bool p_priorThumbnail = false, bool p_prompt = true)
        {
            if (State != FileItemState.None || string.IsNullOrEmpty(ID))
            {
                if (p_prompt)
                {
                    Kit.Warn("当前状态不可下载!");
                }
                return(false);
            }

            bool downloadThumb = false;

            if (p_priorThumbnail)
            {
                // 优先下载缩略图时,先判断是否存在
                downloadThumb = await AtFile.Exists(ID + ThumbPostfix);

                // 缩略图不存在时,若为视频文件不下载
                if (!downloadThumb && FileType != FileItemType.Image)
                {
                    return(false);
                }
            }

            string     path   = Path.Combine(Kit.CachePath, downloadThumb ? GetThumbName() : GetFileName());
            FileStream stream = null;

            try
            {
                if (System.IO.File.Exists(path))
                {
                    System.IO.File.Delete(path);
                }
                stream = System.IO.File.Create(path);
            }
            catch (Exception ex)
            {
                if (p_prompt)
                {
                    Kit.Warn("创建文件出错!");
                }
                Log.Error(ex, "下载前创建文件出错!");
                return(false);
            }

            State = FileItemState.Downloading;
            DownloadInfo info = new DownloadInfo
            {
                Path      = downloadThumb ? ID + ThumbPostfix : ID,
                TgtStream = stream,
                Progress  = OnDownloadProgress,
            };

            bool suc = false;

            _ctsDownload?.Dispose();
            _ctsDownload = new CancellationTokenSource();
            try
            {
                suc = await Downloader.GetFile(info, _ctsDownload.Token);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "下载出错");
            }
            finally
            {
                _ctsDownload?.Dispose();
                info.TgtStream.Close();
                State = FileItemState.None;
            }

            if (!suc)
            {
                if (p_prompt)
                {
                    Kit.Warn(info.Error);
                }

                // 未成功,删除缓存文件,避免打开时出错
                try
                {
                    // mono中 FileInfo 的 Exists 状态不同步!
                    if (System.IO.File.Exists(path))
                    {
                        System.IO.File.Delete(path);
                    }
                }
                catch { }
            }
            else
            {
                VisualStateManager.GoToState(this, "Cached", true);
            }
            return(suc);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 下载文件,将下载内容写入目标流
        /// </summary>
        /// <param name="p_info">下载描述</param>
        /// <param name="p_token"></param>
        /// <returns>是否成功</returns>
        public static async Task <bool> GetFile(DownloadInfo p_info, CancellationToken p_token)
        {
            if (p_info == null || string.IsNullOrEmpty(p_info.Path) || p_info.TgtStream == null)
            {
                return(false);
            }

            HttpResponseMessage response = null;

            using (await _locker.LockAsync())
                using (var request = CreateRequestMessage(p_info.Path))
                {
                    try
                    {
                        response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, p_token).ConfigureAwait(false);
                    }
                    catch (TaskCanceledException)
                    {
                        p_info.Error = "已取消下载!";
                        return(false);
                    }
                    catch (Exception ex)
                    {
                        p_info.Error = "😢下载过程中出错!" + ex.Message;
                        return(false);
                    }
                }

            // 下载失败
            if (response.Headers.TryGetValues("error", out var vals))
            {
                p_info.Error = WebUtility.UrlDecode(vals.First());
                return(false);
            }

            // 文件长度
            long total;

            if (!response.Content.Headers.TryGetValues("Content-Length", out var lgh) || !long.TryParse(lgh.First(), out total))
            {
                p_info.Error = "😢待下载的文件长度未知,下载失败!";
                return(false);
            }

            try
            {
                using (var inputStream = await response.Content.ReadAsStreamAsync())
                {
                    int    read;
                    int    readTotal = 0;
                    byte[] data      = new byte[81920];
                    while ((read = await inputStream.ReadAsync(data, 0, data.Length, p_token).ConfigureAwait(false)) > 0)
                    {
                        await p_info.TgtStream.WriteAsync(data, 0, read);

                        readTotal += read;
                        p_info.Progress?.Invoke(read, readTotal, total);
                    }
                    await p_info.TgtStream.FlushAsync();
                }
            }
            catch (TaskCanceledException)
            {
                p_info.Error = "已取消下载!";
                return(false);
            }
            catch (Exception ex)
            {
                p_info.Error = "😢下载过程中出错!" + ex.Message;
                return(false);
            }
            return(true);
        }