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来发现当前的配额大小,然后添加获得新请求的配额所需的额外金额。

该方法返回TrueFalse来指示我们是否分配了我们所要求的内容。请注意,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>

这是增加配额的点击事件的实现。

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。

隔离增加配额

当您单击“是”时,它会打印出可用配额的数量。

增加配额

我们建议您执行上述示例以便更好地理解。