其实在我的 WebClient的使用文章中的例子就是如何使用WebClient读取zip文件中的资源,这篇文章是在其基础上增加了一些功能,从而构建出一个简单但较为完整的Demo。
首先看看Demo的截图:【示例源码】
下面我将一步步展示实现这个Demo的过程,这个需求就是读出Zip文件中的图片与视频。
Demo整体架构:
首先我们准备几张图片和视频,然后将其压缩至resource.zip文件中,做完之后,我们建立一个resource.xml文件记录压缩包内的资源
- <?xml version="1.0" encoding="utf-8" ?>
- <files>
- <file type="video" name="a.wmv"/>
- <file type="image" name="1.jpg"/>
- <file type="image" name="2.jpg"/>
- <file type="image" name="3.jpg"/>
- <file type="image" name="4.jpg"/>
- </files>
这个xml文件就记录了文件的类型和名称,完成之后我们将其压缩至resource.zip中(请注意:这一步对后面读取流会有影响)
现在我们将UI设计好
- <Image x:Name="Image" />
- <MediaElement x:Name="Video" />
- <StackPanel HorizontalAlignment="Left" VerticalAlignment="Bottom" Opacity="0.5" Orientation="Horizontal" Margin="5,0,0,0" Name="stack">
- <Button Content="Prev" x:Name="PrevButton" Height="30" Margin="0,0,5,0" Width="80" Opacity="1" Cursor="Hand" IsEnabled="False" />
- <Button x:Name="NextButton" Height="30" Margin="0,0,5,0" Width="80" Opacity="1" Content="Next" Cursor="Hand" IsEnabled="False" />
- </StackPanel>
在UI上放置了一个Image和MediaElement控件来显示读取的资源
下面我们开始建立ResourceInfo.cs文件
- public enum ResourceType
- {
- Video,
- Image
- }
- public class ResourceInfo
- {
- public ResourceType Type
- {
- get; set;
- }
- public string Name
- {
- get; set;
- }
- }
文件的类型以枚举的形式表示,现在我们就在MainPage.xaml.cs中以WebClient完成数据的读取工作
先声明3个类成员变量:
- private StreamResourceInfo zip;
- private List<ResourceInfo> resourceInfo;
- private int index = 0;
现在我们就先获取流,其完整代码:
- public void Load(object sender,RoutedEventArgs e)
- {
- Uri uri = new Uri(HtmlPage.Document.DocumentUri, "resource.zip");
- WebClient webClient = new WebClient();
- webClient.OpenReadCompleted += (obj, args) =>
- {
- if (args.Error != null)
- {
- return;
- }
- // 这几步将读出的流信息封装到reader中,这样便于后面使用Linq To Xml操作
- zip = new StreamResourceInfo(args.Result, null);
- StreamResourceInfo maininfo = Application.GetResourceStream(zip, new Uri("resource.xml", UriKind.Relative));
- StreamReader reader = new StreamReader(maininfo.Stream);
- XDocument doc = XDocument.Load(reader);
- var file = from c in doc.Descendants("file")
- select new ResourceInfo
- {
- Type = (ResourceType)Enum.Parse(typeof(ResourceType), c.Attribute("type").Value, true),
- Name = c.Attribute("name").Value
- };
- resourceInfo = new List<ResourceInfo>();
- resourceInfo.AddRange(file);
- this.PrevButton.IsEnabled = true;
- this.NextButton.IsEnabled = true;
- Display(resourceInfo[0]);
- };
- webClient.OpenReadAsync(uri);
- }
- public void Display(ResourceInfo resource)
- {
- //获取相应的流数据
- StreamResourceInfo media = Application.GetResourceStream(zip,new Uri(resource.Name,UriKind.Relative));
- switch (resource.Type)
- {
- case ResourceType.Image:
- Image.Visibility = Visibility.Visible;
- Video.Visibility = Visibility.Collapsed;
- BitmapImage image = new BitmapImage();
- image.SetSource(media.Stream);
- Image.Source = image;
- break;
- case ResourceType.Video:
- Image.Visibility = Visibility.Collapsed;
- Video.Visibility = Visibility.Visible;
- Video.SetSource(media.Stream);
- Video.Play();
- break;
- }
- }
事实上加载这段代码后,我们已经可以将xml文件中标注的第一个资源a.wmv在页面进行成功的播放了
我们继续界面上的Button实现的循环显示上一条,下一条资源功能
- private void StopVideo()
- {
- if (resourceInfo[index].Type == ResourceType.Video)
- {
- Video.Stop();
- }
- }
- private void PrevButton_Click(object sender, RoutedEventArgs e)
- {
- StopVideo();
- if (--index < 0)
- {
- index = resourceInfo.Count - 1;
- }
- Display(resourceInfo[index]);
- }
- private void NextButton_Click(object sender, RoutedEventArgs e)
- {
- StopVideo();
- if (++index >=resourceInfo.Count)
- {
- index = 0;
- }
- Display(resourceInfo[index]);
- }