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)"; 
      } 
   }
}

编译并执行上述代码后,您将看到以下网页,该网页将向您显示您运行此应用程序的次数。

Isolated storage

增加配额

如果初始数量不足,应用程序可能会请求更多空间。不能保证请求会成功。Silverlight 将询问用户是否同意为应用程序提供更多空间。

顺便说一句,您只允许响应用户输入(例如单击)请求更多存储空间。如果您尝试在其他时间请求它,例如插件加载时或在计时器处理程序中,Silverlight 将自动失败请求,甚至不会提示用户。额外的配额仅适用于用户正在交互的应用程序。

IsolatedStorageFile对象提供三个用于管理配额的成员:

  • AvailableFreeSpace (可用空间)
  • IncreaseQuotaTo (增加配额到)
  • Quota (配额)

AvailableFreeSpace (可用空间)

AvailableFreeSpace 属性告诉您还有多少配额可用。

请注意,即使是空的子目录也会消耗一部分配额,因为操作系统需要分配磁盘空间来表示该目录。因此,可用空间可能小于总配额减去所有文件的大小之和。

IncreaseQuotaTo (增加配额到)

如果您没有足够的可用空间继续操作,则可以通过调用IncreaseQuotaTo方法来请求更多空间。

Quota (配额)

在这里,我们使用第三个属性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!"; 
               } 
         } 
      } 
   } 
} 

编译并执行上述代码后,您将看到以下输出。

Isolated storage Quota

单击增加后,将出现提示。它要求将配额增加到比现有配额大 10KB。

Isolated Increase Quota

单击后,它将打印出可用的配额数量。

Increase Quota

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

广告