原文:
与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件
与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件
作者:webabcd
介绍
与众不同 windows phone 8.0 之 文件系统
- 通过 StorageFolder 和 StorageFile 实现文件的读写
- 通过 Uri 引用文件
- 获取 SD 卡中的内容
示例
1、演示如何通过 StorageFolder 和 StorageFile 实现文件的读写
FileSystem/ReadWriteDemo.xaml
<phone:PhoneApplicationPage x:Class="Demo.FileSystem.ReadWriteDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid Background="Transparent"> <StackPanel Orientation="Vertical"> <TextBlock x:Name="lblMsg" /> <Button x:Name="btnWrite" Content="写文件" Click="btnWrite_Click" /> <Button x:Name="btnRead" Content="读文件" Click="btnRead_Click" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
FileSystem/ReadWriteDemo.xaml.cs
/* * 演示如何通过 StorageFolder 和 StorageFile 实现文件的读写 * * * StorageFolder - 用于文件夹的相关操作 * StorageFile - 用于文件的相关操作 * * 注:wp8 中无 win8 中的 FileIO 帮助类,所有文件夹和文件的操作都集成到了 StorageFolder 和 StorageFile 内 * * * wp8 的文件操作部分继承了 win8,详细信息请参见,本文不再详述 * http://www.cnblogs.com/webabcd/archive/2013/04/25/3041569.html * http://www.cnblogs.com/webabcd/archive/2013/05/06/3062064.html * http://www.cnblogs.com/webabcd/archive/2013/05/09/3068281.html * * wp7 的文件操作以前也写过,详细信息请参见 * http://www.cnblogs.com/webabcd/archive/2012/06/20/2555653.html * http://www.cnblogs.com/webabcd/archive/2012/06/25/2560696.html * * * 另:本地存储的资源管理器请参见 * http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/hh286408 * http://wptools.codeplex.com/ */ using System; using System.Windows; using Microsoft.Phone.Controls; using Windows.Storage; using System.IO; using System.Text; using Windows.Storage.Streams; namespace Demo.FileSystem { public partial class ReadWriteDemo : PhoneApplicationPage { public ReadWriteDemo() { InitializeComponent(); } // 写文件的 Demo private async void btnWrite_Click(object sender, RoutedEventArgs e) { // 获取应用程序数据存储文件夹 StorageFolder applicationFolder = ApplicationData.Current.LocalFolder; // 在指定的应用程序数据存储文件夹内创建指定的文件 StorageFile storageFile = await applicationFolder.CreateFileAsync("webabcdTest.txt", CreationCollisionOption.ReplaceExisting); // 将指定的文本内容写入到指定的文件 using (Stream stream = await storageFile.OpenStreamForWriteAsync()) { byte[] content = Encoding.UTF8.GetBytes(DateTime.Now.ToString()); await stream.WriteAsync(content, 0, content.Length); } } // 读文件的 Demo private async void btnRead_Click(object sender, RoutedEventArgs e) { // 获取应用程序数据存储文件夹 StorageFolder applicationFolder = ApplicationData.Current.LocalFolder; StorageFile storageFile = null; try { // 在指定的应用程序数据存储文件夹中查找指定的文件 storageFile = await applicationFolder.GetFileAsync("webabcdTest.txt"); } catch (System.IO.FileNotFoundException ex) { // 没找到指定的文件 lblMsg.Text = "没有找到对应的文件"; } // 获取指定的文件的文本内容 if (storageFile != null) { IRandomAccessStreamWithContentType accessStream = await storageFile.OpenReadAsync(); using (Stream stream = accessStream.AsStreamForRead((int)accessStream.Size)) { byte[] content = new byte[stream.Length]; await stream.ReadAsync(content, 0, (int)stream.Length); lblMsg.Text = Encoding.UTF8.GetString(content, 0, content.Length); } } } } }
2、演示如何通过 Uri 引用文件,以及对各种文件路径做简要说明
FileSystem/UriDemo.xaml
<phone:PhoneApplicationPage x:Class="Demo.FileSystem.UriDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid Background="Transparent"> <StackPanel Orientation="Vertical"> <TextBlock Name="lblMsg" TextWrapping="Wrap" /> <Image Name="img1" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img2" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img3" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img4" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img5" Width="50" Height="50" Margin="0 5 0 0" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
FileSystem/UriDemo.xaml.cs
/* * 演示如何通过 Uri 引用文件,以及对各种文件路径做简要说明 * * * 由于引入了 win8 文件管理模型,所以 StorageFile 可以支持 ms-appx:/// 和 ms-appdata:///local/(roaming 和 temp 不支持) */ using System; using System.Windows; using System.Windows.Navigation; using Microsoft.Phone.Controls; using System.Windows.Media.Imaging; using Windows.Storage; using System.IO; using System.Windows.Resources; using Windows.ApplicationModel; using System.Threading.Tasks; using System.IO.IsolatedStorage; namespace Demo.FileSystem { public partial class UriDemo : PhoneApplicationPage { public UriDemo() { InitializeComponent(); } protected async override void OnNavigatedTo(NavigationEventArgs e) { // Package 内的文件管理 await PackageDemo(); // Application Data(只支持 LocalFolder,RoamingFolder 和 TemporaryFolder 目前都不支持)内的文件管理 await ApplicationDataDemo(); // Isolated Storage(其在 Application Data 的 Local\IsolatedStore\ 目录下)内的文件管理 IsolatedStorageDemo(); // 本地数据库 DataContextDemo(); base.OnNavigatedTo(e); } // 引用 Package 中的文件,介绍 Package 中的文件路径 private async Task PackageDemo() { // Package 所在路径 StorageFolder packageFolder = Package.Current.InstalledLocation; lblMsg.Text += "Package 路径:" + packageFolder.Path; lblMsg.Text += Environment.NewLine; // 引用 Package 内的媒体类文件 img1.Source = new BitmapImage(new Uri("/Assets/AppIcon.png", UriKind.Relative)); // 引用 Package 中的内容文件(此方式需要以“/”开头) // img1.Source = new BitmapImage(new Uri("/Demo;component/Assets/AppIconResource.png", UriKind.Relative)); // 引用 Package 中的资源文件(需要以“/”开头) // 通过 StreamResourceInfo 方式获取 Package 内的文件 StreamResourceInfo sri = Application.GetResourceStream(new Uri("Assets/AppIcon.png", UriKind.Relative)); // 引用 Package 中的内容文件(此方式不能以“/”开头) // StreamResourceInfo sri = Application.GetResourceStream(new Uri("/Demo;component/Assets/AppIconResource.png", UriKind.Relative)); // 引用 Package 中的资源文件(需要以“/”开头) Stream stream = sri.Stream; BitmapImage bi = new BitmapImage(); bi.SetSource(stream); img2.Source = bi; // 通过 win8 方式获取 Package 内的文件 StorageFile imgFilePackage = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/AppIcon.png", UriKind.Absolute)); using (var sourceFile = await imgFilePackage.OpenStreamForReadAsync()) { BitmapImage image = new BitmapImage(); image.SetSource(sourceFile); img3.Source = image; } } private async Task ApplicationDataDemo() { // 从 Package 复制文件到 ApplicationData // 路径为:C:\Data\Users\DefApps\AppData\{ProductID}\Local\ StorageFolder applicationFolder = ApplicationData.Current.LocalFolder; // 注:RoamingFolder 和 TemporaryFolder 目前都不支持 StorageFile imgFilePackage = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/AppIcon.png", UriKind.Absolute)); await imgFilePackage.CopyAsync(applicationFolder, "AppIcon.png", NameCollisionOption.ReplaceExisting); // 获取 ApplicationData 中的文件 StorageFile imgFileApplicationData = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appdata:///Local/AppIcon.png", UriKind.Absolute)); using (var sourceFile = await imgFileApplicationData.OpenStreamForReadAsync()) { BitmapImage image = new BitmapImage(); image.SetSource(sourceFile); img4.Source = image; } } private void IsolatedStorageDemo() { // 从 Package 复制文件到 IsolatedStorage // 路径为:C:\Data\Users\DefApps\AppData\{ProductID}\Local\IsolatedStore\ IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication(); using (Stream input = Application.GetResourceStream(new Uri("Assets/AppIcon.png", UriKind.Relative)).Stream) { using (IsolatedStorageFileStream output = isf.CreateFile("AppIcon.png")) { byte[] readBuffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = input.Read(readBuffer, 0, readBuffer.Length)) > 0) { output.Write(readBuffer, 0, bytesRead); } } } // 获取 IsolatedStorage 中的文件 using (var isfs = new IsolatedStorageFileStream(@"AppIcon.png", FileMode.OpenOrCreate, isf)) { BitmapImage bi = new BitmapImage(); bi.SetSource(isfs); img5.Source = bi; } } private void DataContextDemo() { // 引用 Package 中的数据库文件用 appdata:/ // 引用 IsolatedStorage 中的数据库文件用 isostore:/ // 关于本地数据库的详细信息请参见:http://www.cnblogs.com/webabcd/archive/2012/06/25/2560696.html } } }
3、演示如何获取 SD 卡中的内容
FileSystem/SDDemo.xaml
<phone:PhoneApplicationPage x:Class="Demo.FileSystem.SDDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid Background="Transparent"> <StackPanel Orientation="Vertical"> <TextBlock Name="lblMsg" TextWrapping="Wrap" /> <Image Name="img1" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img2" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img3" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img4" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img5" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img6" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img7" Width="50" Height="50" Margin="0 5 0 0" /> <Image Name="img8" Width="50" Height="50" Margin="0 5 0 0" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
FileSystem/SDDemo.xaml.cs
/* * 演示如何获取 SD 卡中的内容 * 查看本 Demo 前需要现在 sd 卡根目录下创建几个文件夹和几个有内容的 .log 文件 * * * ExternalStorage - sd 存储 * GetExternalStorageDevicesAsync() - 获取 sd 存储设备集合 * * ExternalStorageDevice - sd 存储设备 * ExternalStorageID - 唯一标识 * RootFolder - 根目录 * GetFolderAsync(string folderPath) - 获取指定路径的文件夹 * GetFileAsync(string filePath) - 获取指定路径的文件 * * ExternalStorageFolder - sd 存储设备中的文件夹 * Name - 文件夹名称 * Path - 文件夹路径 * DateModified - 上次修改的日期 * GetFoldersAsync() - 获取当前文件夹的顶级子文件夹列表 * GetFolderAsync(string name) - 获取指定路径的单个子文件夹 * GetFilesAsync() - 获取当前文件夹内的顶级文件列表 * * ExternalStorageFile - sd 存储设备中的文件 * Name - 文件名称 * Path - 文件路径 * DateModified - 上次修改的日期 * OpenForReadAsync() - 打开文件流以读取文件 * * * 注: * 1、对 sd 存储的操作只有读取的权限 * 2、文件夹 Music, Pictures, Videos, WPSystem 中的内容无法通过 ExternalStorage 获取 * 3、在 manifest 中增加配置 <Capability Name="ID_CAP_REMOVABLE_STORAGE" /> * 4、在 manifest 中增加类似如下的配置 * <Extensions> <!--关于 FileTypeAssociation 详见《关联启动》--> <FileTypeAssociation TaskID="_default" Name="myFileTypeAssociation" NavUriFragment="fileToken=%s"> <Logos> <Logo Size="small" IsRelative="true">Assets/AppIcon_33x33.png</Logo> <Logo Size="medium" IsRelative="true">Assets/AppIcon_69x69.png</Logo> <Logo Size="large" IsRelative="true">Assets/AppIcon_176x176.png</Logo> </Logos> <SupportedFileTypes> <!--只能访问此处声明过的类型的文件--> <FileType ContentType="text/plain">.log</FileType> <FileType ContentType="application/rar">.rar</FileType> </SupportedFileTypes> </FileTypeAssociation> </Extensions> */ using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Navigation; using Microsoft.Phone.Controls; using Microsoft.Phone.Storage; using System.IO; namespace Demo.FileSystem { public partial class SDDemo : PhoneApplicationPage { public SDDemo() { InitializeComponent(); } protected async override void OnNavigatedTo(NavigationEventArgs e) { // 获取 sd 卡设备 ExternalStorageDevice sdCard = (await ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault(); if (sdCard != null) { try { // 遍历根目录下的文件夹 ExternalStorageFolder rootFolder = sdCard.RootFolder; IEnumerable<ExternalStorageFolder> folders = await rootFolder.GetFoldersAsync(); foreach (ExternalStorageFolder folder in folders) { lblMsg.Text += folder.Name; lblMsg.Text += Environment.NewLine; } // 遍历根目录下的文件 IEnumerable<ExternalStorageFile> files = await rootFolder.GetFilesAsync(); foreach (ExternalStorageFile file in files) { lblMsg.Text += file.Name; lblMsg.Text += Environment.NewLine; // 获取文件的内容 if (Path.GetExtension(file.Path) == ".log") ReadFile(file); } } catch (FileNotFoundException ex) { MessageBox.Show("没有找到相关的文件或文件夹"); } } else { MessageBox.Show("没有找到 sd 卡"); } base.OnNavigatedTo(e); } private async void ReadFile(ExternalStorageFile file) { // 获取文件的内容 Stream stream = await file.OpenForReadAsync(); using (StreamReader sr = new StreamReader(stream)) { lblMsg.Text += sr.ReadToEnd(); lblMsg.Text += Environment.NewLine; } } } }
OK
[源码下载]