现在的位置: 首页 > 综合 > 正文

跨Windows Phone 8和Windows 8(WinRT)的简单文件系统访问

2012年12月22日 ⁄ 综合 ⁄ 共 2769字 ⁄ 字号 评论关闭

说实话最初看到Windows Phone 8 SDK我略感失望,因为这个坑了诺基亚,抛弃了无数Windows Phone 7用户的新平台,并没有和Windows 8的WinRT完全接轨,Windows Phone 8虽然运行着Windows 8的内核,但在开发上和Windows 8的WinRT的交集并不是很多,而Windows 8的开发,才像是全新的开始。比尔盖茨前一阵还说Windows Phone和Windows最终会成为一个操作系统(参考链接1 链接2),但愿这个梦早点实现,如果说WinRT就是微软最终的梦,那么Windows 8已经走在前列了(但是WinRT仍需大力开发使之更成熟强大),而Windows Phone 8只能抱歉地说我还有一些路要走。

 

好了,吐槽了挺多,下面正文,我简单讲讲Windows Phone 8和Windows 8(WinRT)的一个交集:文件系统。

注意:Windows Phone 8的winmd在"C:\Program Files (x86)\Windows Phone Kits\8.0\Windows MetaData\Windows.winmd"中,而WinRT的文件系统独立在一个winmd文件中:"C:\Windows\System32\WinMetadata\Windows.Storage.winmd"

 

Windows Phone 8的文件系统可以看作是WinRT的子集,它们有共同的名称,共同的命名空间,Windows Phone 8会剪掉某些类型的执行,而且已执行类型的限制相比WinRT也可能更多。比如Windows Phone 8中没有PathIO和FileIO类型,还比如在Windows.Storage.Pickers命名空间中Windows Phone 8只有FileOpenPicker为没有WinRT的FolderPicker,显然Windows Phone 8的限制更多,即便是都拥有的FileOpenPicker都如此。

 

但是它们核心元素还是一样的,比如IStorageItem代表文件系统对象:

image

还有新的Stream相关类型:

image

这些在这两个平台都几乎是一样的。

 

OK,现在就开始写一个利用这个通用文件系统的简单小程序:输出一个StorageFolder中的所有内容。为了最简单化,界面上我们就用一个TextBlock用作输出,然后加一个Loaded事件:

<TextBlock Name="tbl" Loaded="tbl_Loaded_1"/>

 

注意虽然在界面元素上Windows Phone 8和Windows 8(WinRT)都是使用XAML,但是Windows Phone 8的XAML是沿用Windows Phone 7以System.Windows命名空间为主的。而WinRT的XAML是以Windows.UI.Xaml命名空间为核心的。

 

注意还需要引用我们需要的相关命名空间(显然后期Windows应用程序开发的命名空间开始有些凌乱了,记住以System开头的通常是.NET中的类型,以Windows开头的命名空间通常是WinRT框架相关的类型):

using Windows.ApplicationModel;  //Package类型

using Windows.Storage;           //StorageFolder等类型

using System.Threading.Tasks;    //Task类型

using System.Text;               //StringBuilder类型

 

接着开始定义主方法,我们通过最简单的StorageFolder的GetFolders和GetFiles方法来递归输出文件夹内的所有内容(注意,Windows Phone 8和WinRT的开发都是异步化驱动的):

//异步输出文件夹信息

static async Task ShowContentAsync(StringBuilder sb, StorageFolder dir, int indent)

{

    //缩进相关变量

    var currentIndentStr = new string(' ', indent);

    var nextIndent = indent + 4;

    var nextIndentStr = new string(' ', nextIndent);

 

    //输出当前文件夹名称

    sb.Append(currentIndentStr);

    sb.AppendLine("> " + dir.Name);

 

    //输出并递归子文件夹

    foreach (var folder in await dir.GetFoldersAsync())

        await ShowContentAsync(sb, folder, nextIndent);

    //输出子文件

    foreach (var file in await dir.GetFilesAsync())

        sb.AppendLine(nextIndentStr + file.Name);

}

 

最后在TextBlock的Loaded事件中加入调用代码,注意需把它改成async方法。至于需要探索的文件夹,我们选择当前应用程序的安装文件夹(通过Windows.ApplicationModel命名空间中的Package类型中的InstalledLocation属性),也可以选择其他默认授权访问的文件夹,比如应用程序本地数据文件夹(通过Windows.Storage命名空间中的ApplicationData.Current.LocalFolder属性):

//Loaded事件

private async void tbl_Loaded_1(object sender, RoutedEventArgs e)

{

    //创建一个StringBuilder

    var sb = new StringBuilder();

    //把应用程序的安装文件夹作为参数并运行方法

    await ShowContentAsync(sb, Package.Current.InstalledLocation, 0);

    //把结果设置到界面上的TextBlock

    tbl.Text = sb.ToString();

}

 

注意虽然开发代码是一样的,但不同操作系统的应用程序必须经相应编译器编译,我们仍然是为两个系统开发两个程序,只不过代码是一样的。仍然需要Visual Studio 2012 Express for Windows 8和Visual Studio Express for Windows Phone分别建立并编译工程。(当然比尔盖茨的话要是实现的话,就不需要了。)

 

在Windows Phone 8下的运行结果:

image

 

在Windows 8(WinRT)的运行结果:

image

抱歉!评论已关闭.