Silverlight - 隔离存储
第三种文件访问机制是隔离存储机制,它提供与登录用户关联的存储。 API 通过 .NET System.IO 命名空间中的 Stream 类呈现数据。 因此,与我们迄今为止讨论的其他机制一样,您可以使用 System.IO 中的其他类型来处理流,从而使您能够存储文本或二进制数据。
一些重要的功能是 −
此存储机制称为隔离存储,因为存储是分区的,并且 Silverlight 应用程序只能访问某些部分。
您无法访问任何旧存储的数据。 首先,存储按用户进行分区。 Silverlight 应用程序无法为登录并运行该应用程序的用户以外的其他用户访问存储区。
这与您的 Web 应用程序可能使用的任何识别机制无关。 这是需要记住的重要一点,因为一些共享计算机的人不会费心使用单独的 Windows 帐户,而习惯于仅登录和退出他们使用的网站。
使用隔离存储
独立存储并不是 Silverlight 独有的。 该 API 最初是为 Windows 窗体 引入的,以使从 Web 启动的应用程序能够在部分信任的情况下在本地存储数据。 实现不同,无法从 Silverlight 访问完整的 .NET Framework 的独立存储,反之亦然。
但是,如果您使用过它,那么这里的步骤会看起来非常熟悉。
您首先询问用户特定的商店。 在这种情况下,我们要求提供用于申请的一份。 如果我们希望站点上的所有 XAP 共享每个站点的存储,我们将调用 GetUserStoreForSite。
这两种方法都会返回一个 IsolatedStorageFile 对象,这是一个非常无用的名称,因为它代表一个目录,而不是文件。
要访问文件,您需要向IsolatedStorageFile请求Stream。
我们使用 IsolatedStorageFileStream 类,其构造函数要求您将 IsolatedStorageFile 对象作为参数传递。
因此我们正在商店中创建一个新文件。 该文件在磁盘上的确切位置未知。
包含的目录具有随机元素,以便无法猜测文件的名称。
如果没有这个,恶意网站可能会将文件放置在用户的计算机上,然后构造一个文件 URL 来打开它,希望欺骗用户点击本地执行程序的链接。
Windows 中内置了各种其他安全措施,试图防止这种情况发生,但这是另一层防御,以防其他层以某种方式被禁用或绕过。
该文件将存储在用户配置文件内的某个位置,但这就是您所能了解的信息。 您的IsolatedStorageFileStream不会报告其真实位置。
让我们看一个简单的示例,该示例跟踪应用程序已运行的次数。 下面给出的是 XAML 代码。
<UserControl x:Class = "StoreRunCount.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "400"> <Grid x:Name = "LayoutRoot" Background = "White"> <TextBlock x:Name = "runCountText" FontSize = "20" /> </Grid> </UserControl>
以下是使用隔离存储的 C# 代码。
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.IO.IsolatedStorage; using System.IO; namespace StoreRunCount { public partial class MainPage : UserControl { const string RunCountFileName = "RunCount.bin"; public MainPage() { InitializeComponent(); int runCount = 0; using (var store = IsolatedStorageFile.GetUserStoreForApplication()) { if (store.FileExists(RunCountFileName)) { using (var stm = store.OpenFile(RunCountFileName, FileMode.Open, FileAccess.Read)) using (var r = new BinaryReader(stm)) { runCount = r.ReadInt32(); } } runCount += 1; using (var stm = store.OpenFile(RunCountFileName, FileMode.Create, FileAccess.Write)) using (var w = new BinaryWriter(stm)) { w.Write(runCount); } } runCountText.Text = "You have run this application " + runCount.ToString() + " time(s)"; } } }
编译并执行上述代码后,您将看到以下网页,其中会显示您运行此应用程序的次数。
增加您的配额
如果初始空间由于某种原因不足,应用程序可能会要求更多空间。 无法保证请求会成功。 Silverlight 将询问用户是否愿意授予应用程序更多空间。
顺便说一句,您只能在响应用户输入(例如点击)时请求更多存储空间。 如果您尝试在其他时间询问它,例如在插件加载时或在计时器处理程序中,Silverlight 将自动使请求失败,甚至不会提示用户。 额外配额仅适用于与用户交互的应用程序。
IsolatedStorageFile对象提供了三个用于管理配额的成员 −
- 可用空间
- 增加配额
- 配额
可用空间
AvailableFreeSpace 属性告诉您有多少配额仍然可用。
请注意,即使是空子目录也会消耗一些配额,因为操作系统需要在磁盘上分配空间来表示该目录。 因此,可用空间可能小于总配额减去所有文件大小的总和。
增加配额
如果您没有足够的空间来继续,您可以通过调用 IncreaseQuotaTo 方法来请求更多空间。
配额
这里我们使用第三个属性Quota来发现当前的配额大小,然后我们添加获得新请求的配额所需的额外金额。
该方法返回True或False来指示我们是否分配了我们所要求的内容。 请注意,Silverlight 可能会决定分配比您要求的更多的空间。
这是一个简单的示例,用于在单击按钮时增加配额。 下面给出的是 XAML 代码。
<UserControl x:Class = "ChangeQuota.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "400"> <Grid x:Name = "LayoutRoot" Background = "White"> <TextBlock x:Name = "infoText" FontSize = "20" TextWrapping = "Wrap" /> <Button x:Name = "increaseQuota" Content = "Increase" HorizontalAlignment = "Center" FontSize = "20" VerticalAlignment = "Center" Click = "increaseQuota_Click" /> </Grid> </UserControl>
这里是增加配额的click事件的实现。
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.IO.IsolatedStorage; namespace ChangeQuota { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void increaseQuota_Click(object sender, RoutedEventArgs e) { using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { long newQuota = isoStore.Quota + 10240; if (isoStore.IncreaseQuotaTo(newQuota)) { infoText.Text = "Quota is " + isoStore.Quota + ", free space: " + isoStore.AvailableFreeSpace; } else { infoText.Text = "Meanie!"; } } } } }
编译并执行上述代码后,您将看到以下输出。
当您单击增加时,会出现提示。 它要求将配额增加到比现有配额大10KB。
当您单击是时,它会打印出可用配额的数量。
我们建议您执行上述示例以便更好地理解。