使用隔离存储( 一个简单的演示)






4.58/5 (27投票s)
本文将帮助您使用隔离存储类。
引言
隔离存储命名空间包含在 .NET 类库中,是 Visual Studio 2003 或更高版本中引入的一个很好的功能,用于隐藏外部的某些数据。实际存储这些数据的文件对于用户来说有点抽象,并且基于创建应用程序时指定的范围。在本文中,我将讨论如何使用隔离存储类以及如何指定其范围的基础知识。通过隔离存储存储的数据不能被信任度较低的应用程序访问,因为它们的作用域限定在它生成的程序集内。
本项目中我们需要的类如下所示:
IsolatedStorageFile
:这是主要的FileStream
对象。它是管理目录、文件并获取程序集存储的主要类。IsolatedStorageFileStream
:公开隔离文件位置中的文件。它是用于文件读写的主要文件流对象。IsolatedStorageException
:它是隔离文件操作期间生成任何运行时异常时抛出的异常对象。
我们还需要包含 System.IO.IsolatedStorage
。请注意:IsolatedStorage 类包含在 mscorlib.dll 中,它会自动包含。因此不需要引用。
背景
使用文件存储敏感信息是一种非常常见的做法。诸如 Web 服务路径、用户设置、应用程序设置之类的信息存储在注册表、config 文件或某些文本文件中。使用它们的问题在于它们不属于程序集本身,因此每当程序集导出时,它们都应被导出。
使用隔离存储,我们可以将这些数据包含在程序集本身中,这些数据将随该程序集自动传输。我们还可以将信息写入应用程序数据块、系统文件以获得更好的安全性。使用隔离存储可以消除任何不安全的 COM 应用程序访问敏感信息。
Using the Code
这是一个关于如何从隔离存储中写入或获取数据的基本示例。为此,我们需要一个 IsolatedStorageFile
对象。这个类有一个名为 GetStore
的静态函数。我们可以指定我们需要的存储类型。
以下是所有可用范围的列表
成员名称 | 用途描述 |
无 | 不使用隔离存储 |
用户 | 隔离存储范围限定到用户身份 |
定义域 | 隔离存储范围限定到应用程序域身份 |
程序集 | 隔离存储范围限定到程序集的身份 |
漫游 | 隔离存储可以漫游。 |
Machine | 隔离存储范围限定到机器 |
Application | 隔离存储范围限定到应用程序 |
通常我们使用域作为应用程序范围,它标识应用程序域并在应用程序域中存储数据。
现在是理解代码的时候了。
至于基础知识,请看下面的代码
//Main Class that is used for Isolated Storage
using System;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.IO.IsolatedStorage;
namespace IsolatedStorage
{
public partial class ISF : Form
{
private string filename;
private string directoryname;
IsolatedStorageFile isf = null;
/// <summary>
/// Constructor for ISF, Used generally for Initialization
/// </summary>
public ISF()
{
filename = string.Empty;
directoryname = string.Empty;
InitializeComponent();
isf = IsolatedStorageFile.GetStore(IsolatedStorageScope.User|
IsolatedStorageScope.Assembly|IsolatedStorageScope.Domain,
typeof(System.Security.Policy.Url),typeof(System.Security.Policy.Url));
}
/// <summary>
/// Invoked when Button1 is Clicked
/// </summary>
/// <param name="sender">Object that invokes the Event
/// ( Here it is Button1)</param>
/// <param name="e">Event Related Arguments</param>
private void button1_Click(object sender, EventArgs e)
{
LoadInfo();
}
/// <summary>
/// Clear out Existing Loaded Information from the List Boxes
/// </summary>
private void LoadInfo()
{
lstDirectories.Items.Clear();
lstFileList.Items.Clear();
lstFileList.Items.AddRange(isf.GetFileNames("*"));
lstDirectories.Items.AddRange(isf.GetDirectoryNames("*"));
}
/// <summary>
/// Enabling btnSave when Text is Changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void textBox1_TextChanged(object sender, EventArgs e)
{
btnSave.Enabled = true;
}
/// <summary>
/// Called when Save button is clicked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSave_Click(object sender, EventArgs e)
{
try
{
IsolatedStorageFileStream isfs;
isfs = new IsolatedStorageFileStream(Path.Combine(getDirectoryName(),
getFileName()), FileMode.Create, isf);
byte[] data = Encoding.GetEncoding("utf-8").GetBytes(textBox1.Text);
isfs.Write(data, 0, data.Length);
isfs.Close();
LoadInfo();
}
catch (Exception ex)
{
MessageBox.Show("Runtime Error:" + ex.Message);
}
}
/// <summary>
/// Get Directory Name from the user of Session Context
/// </summary>
/// <returns></returns>
private string getDirectoryName()
{
if (directoryname == string.Empty)
{
frmNewName dialog = new frmNewName();
dialog.Text = "Enter Directory Name:";
if (dialog.ShowDialog() == DialogResult.OK)
return dialog.Path;
else
return string.Empty;
}
else
return directoryname;
}
/// <summary>
/// Gets FileName from User or Current Session
/// </summary>
/// <returns></returns>
private string getFileName()
{
if (filename == string.Empty)
{
frmNewName dialog = new frmNewName();
dialog.Text = "Enter File Name:";
if (dialog.ShowDialog() == DialogResult.OK)
return dialog.Path;
else
return string.Empty;
}
else
return filename;
}
/// <summary>
/// Selected Index changed for File. Loads the File to the TextBox also
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lstFileList_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
filename = lstFileList.SelectedItem.ToString();
IsolatedStorageFileStream isfs = new IsolatedStorageFileStream
(Path.Combine(directoryname,filename), FileMode.Open, isf);
StreamReader sr = new StreamReader(isfs);
textBox1.Text = sr.ReadToEnd();
sr.Close();
isfs.Close();
btnSave.Enabled = false;
lblItemStat.Text = Path.Combine(directoryname, filename);
}
catch (FileNotFoundException ex)
{
MessageBox.Show("Runtime Error:" + ex.Message);
}
}
/// <summary>
/// Creates New Directory
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNewDir_Click(object sender, EventArgs e)
{
directoryname = string.Empty;
directoryname = getDirectoryName();
isf.CreateDirectory(directoryname);
LoadInfo();
}
private void btnFile_Click(object sender, EventArgs e)
{
filename = string.Empty;
filename = getFileName();
}
private void lstDirectories_SelectedIndexChanged(object sender, EventArgs e)
{
directoryname = lstDirectories.SelectedItem.ToString();
lstFileList.Items.Clear();
lstFileList.Items.AddRange
(isf.GetFileNames(Path.Combine(directoryname,"*")));
}
/// <summary>
/// Removes currently selected Directory. Note It will
/// throw error if Directory is not Empty
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRemoveDir_Click(object sender, EventArgs e)
{
try
{
isf.DeleteDirectory(lstDirectories.SelectedItem.ToString());
directoryname = string.Empty;
LoadInfo();
}
catch (IsolatedStorageException ex)
{
MessageBox.Show("Runtime Error:" + ex.Message);
}
}
/// <summary>
/// Removes Chosen File
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRemoveFile_Click(object sender, EventArgs e)
{
try
{
isf.DeleteFile(Path.Combine(directoryname,
lstFileList.SelectedItem.ToString()));
filename = string.Empty;
}
catch (IsolatedStorageException ex)
{
MessageBox.Show("Runtime Error:" + ex.Message);
}
}
}
}
这段代码对你来说可能有点冗长。好的,让我们简单定义一下。
要使用隔离存储,我们需要根据所需的范围为数据创建存储。要获取存储,我们将编写
<>IsolatedStorageFile isf = IsolatedStorageFile.GetStore(IsolatedStorageScope.User|
IsolatedStorageScope.Assembly|IsolatedStorageScope.Domain, null,null);>
在上面一行中,我创建了一个 IsolatedStorage
对象,并从当前用户域获取了存储。
获取存储后,我们需要 IsolatedStorageFileStream
来读取或写入特定文件。
IsolatedStorageFileStream isfs = new IsolatedStorageFileStream
("abc.txt",FileMode.Create, isf);
在上面一行中,我创建了一个 IsolatedStorageFileStream
,如果“abc.txt”文件不存在,它将创建该文件。
完成此操作后,我们需要 StreamReader
来读取文件或 StreamWriter
来写入文件。
从文件读取时,我们必须使用 FileMode.Open
以确保如果找不到文件,它会给出文件未找到错误。
//For Reading
StreamReader sr = new StreamReader(isfs);
string fileData = sr.ReadToEnd();//Reads from the File it is pointed to
// For Writing
StreamWriter sw = new StreamWriter(isfs);
sw.WriteLine(fileData); // Writes Data to the File Opened
如果 I/O 操作失败,可能会抛出 IsolatedStorageException
。
这就是我们所需要的。代码中的其他部分只是为了给你呈现一个好的界面。
快照

上图中显示了一个按钮,用于加载目录和文件。GetList
按钮将列出当前范围内存储的所有目录和文件。
我们也可以更改范围以获取其他存储。

保存按钮会将 Textbox
中写入的文件保存到所选文件中。如果尚未选择文件,将显示文件选择对话框。

第三张图片显示了当文件名不存在时弹出的对话框。
尝试运行应用程序并检查。应用程序可能存在一些错误。我很快就会修复它们。
关注点
通过使用隔离存储类的功能,将重要文件隐藏起来不让用户看到真的很有趣。我想你们都会喜欢使用 .NET 提供的这个功能来创建应用程序。
功能矩阵
除了使用 GetStore
函数,你还可以使用 IsolatedStorageFile
类提供的自定义函数。以下是等效矩阵
IsolatedStorageFile.GetMachineStoreForApplication()
等同于
IsolatedStorageFile.GetStore(IsolatedStorageScope.Application |
IsolatedStorageScope.Machine, null, null);
IsolatedStorageFile.GetMachineStoreForAssembly()
等同于
IsolatedStorageFile.GetStore(IsolatedStorageScope.Assembly |
IsolatedStorageScope.Machine, null, null);IsolatedStorageFile.GetMachineStoreForDomain()
等同于
IsolatedStorageFile.GetStore(IsolatedStorageScope.Assembly |
IsolatedStorageScope.Domain | IsolatedStorageScope.Machine, null, null);
IsolatedStorageFile.GetUserStoreForApplication()
等同于
IsolatedStorageFile.GetStore(IsolatedStorageScope.Application |
IsolatedStorageScope.User, null);
IsolatedStorageFile.GetUserStoreForAssembly()
等同于
IsolatedStorageFile.GetStore(IsolatedStorageScope.Assembly |
IsolatedStorageScope.User, null, null);
IsolatedStorageFile.GetUserStoreForDomain()
等同于
IsolatedStorageFile.GetStore(IsolatedStorageScope.Assembly |
IsolatedStorageScope.Domain | IsolatedStorageScope.User, null, null);
你可以使用这些函数中的任何一个来获取其存储。
历史
这是本文的第一个版本。我稍后会更新应用程序,使其更方便。
第一个版本: IsolatedStorage.zip - 这是应用程序的第一个版本。它可能包含一些错误。我将在未来的修订中修复它们。我的目的是提供有关系统使用的基本知识。