Silverlight中的独立存储有以下一些特征:
1.每个基于Silverlight的应用程序都被分配了属于它自己的一部分存储空间,但是应用程序中的程序集却是在存储空间中共享的。一个应用程序被服务器赋给了一个唯一的固定的标识值。基于Silverlight的应用程序的虚拟文件系统现在就以一个标识值的方式来访问了。这个标识值必须是一个常量,这样每次应用程序运行时才可以找到这个共享的位置。
2.独立存储的APIs 其实和其它的文件操作APIs类似,比如 File 和 Directory 这些用来访问和维护文件或文件夹的类。 它们都是基于FileStream APIs 来维护文件的内容的。
3.独立存储严格的限制了应用程序可以存储的数据的大小,目前的上限是每个应用程序为1 MB。
使用独立存储
Silverlight中的独立存储功能通过密封类IsolatedStorageFile来提供,位于命名空间System.IO.IsolatedStorag中,IsolatedStorageFile类抽象了独立存储的虚拟文件系统。创建一个 IsolatedStorageFile 类的实例,可以使用它对文件或文件夹进行列举或管理。同样还可以使用该类的 IsolatedStorageFileStream 对象来管理文件内容,它的定义大概如下所示:
下面来看各个功能的实现:
创建目录,直接使用CreateDirectory方法就可以了,另外还可以使用DirectoryExistes方法来判断目录是否已经存在:
void btnCreateDirectory_Click(object sender,RoutedEventArgs e)
{
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication())
{
String directoryName = this.txtDirectoryName.Text;
if (this.lstDirectories.SelectedItem != null)
{
directoryName = System.IO.Path.Combine(this.lstDirectories.SelectedItem.ToString(),
directoryName);
}
if (!store.DirectoryExists(directoryName))
{
store.CreateDirectory(directoryName);
HtmlPage.Window.Alert("创建目录成功!");
}
}
}
创建文件,通过CreateFile方法来获取一个IsolatedStorageFileStream,并将内容写入到文件中:
void btnCreateFile_Click(object sender,RoutedEventArgs e)
{
if (this.lstDirectories.SelectedItem == null &&
this.txtDirectoryName.Text == "")
{
HtmlPage.Window.Alert("请先选择一个目录或者输入目录名");
return;
}
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication())
{
String filePath;
if (this.lstDirectories.SelectedItem == null)
{
filePath = System.IO.Path.Combine(this.txtDirectoryName.Text,
this.txtFileName.Text + ".txt");
}
else
{
filePath = System.IO.Path.Combine(this.lstDirectories.SelectedItem.ToString(),
this.txtFileName.Text + ".txt");
}
IsolatedStorageFileStream fileStream = store.CreateFile(filePath);
using (StreamWriter sw = new StreamWriter(fileStream))
{
sw.WriteLine(this.txtFileContent.Text);
}
fileStream.Close();
HtmlPage.Window.Alert("写入文件成功!");
}
}
读取文件,直接使用System.IO命名空间下的StreamReader:
void btnReadFile_Click(object sender,RoutedEventArgs e)
{
if (this.lstDirectories.SelectedItem == null
this.lstFiles.SelectedItem == null)
{
HtmlPage.Window.Alert("请先选择目录和文件!");
return;
}
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication())
{
String filePath = System.IO.Path.Combine(this.lstDirectories.SelectedItem.ToString(),
this.lstFiles.SelectedItem.ToString());
if (store.FileExists(filePath))
{
StreamReader reader = new StreamReader(store.OpenFile(filePath,
FileMode.Open,FileAccess.Read));
this.txtFileContent.Text = reader.ReadToEnd();
this.txtDirectoryName.Text = this.lstDirectories.SelectedItem.ToString();
this.txtFileName.Text = this.lstFiles.SelectedItem.ToString();
}
}
}
删除目录和文件:
void btnDeleteFile_Click(object sender,RoutedEventArgs e)
{
if (this.lstDirectories.SelectedItem != null &&
this.lstFiles.SelectedItem != null)
{
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication())
{
String filePath = System.IO.Path.Combine(this.lstDirectories.SelectedItem.ToString(),
this.lstFiles.SelectedItem.ToString());
store.DeleteFile(filePath);
HtmlPage.Window.Alert("删除文件成功!");
}
}
}
void btnDeleteDirectory_Click(object sender,RoutedEventArgs e)
{
if (this.lstDirectories.SelectedItem != null)
{
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication())
{
store.DeleteDirectory(this.lstDirectories.SelectedItem.ToString());
HtmlPage.Window.Alert("删除目录成功!");
}
}
}
获取目录列表和文件列表:
void lstDirectories_SelectionChanged(object sender,SelectionChangedEventArgs e)
{
if (lstDirectories.SelectedItem != null)
{
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication())
{
String[] files = store.GetFileNames(
this.lstDirectories.SelectedItem.ToString() + "/");
this.lstFiles.ItemsSource = files;
}
}
}
void BindDirectories()
{
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication())
{
String[] directories = store.GetDirectoryNames("*");
this.lstDirectories.ItemsSource = directories;
}
}
{
string fileName = @"MyLog.txt";
using (IsolatedStorageFile store =
{
IsolatedStorageFileStream fileStream;
if (!store.FileExists(fileName))
{
fileStream = store.CreateFile(fileName);
}
else
{
fileStream = store.OpenFile(fileName,FileMode.Append,FileAccess.Write);
}
using (StreamWriter sw = new StreamWriter(fileStream))
{
sw.WriteLine("aa");
}
fileStream.Close();
}
}
增加配额
在本文一开始我就提到独立存储严格的限制了应用程序可以存储的数据的大小,但是我们可以通过IsolatedStorageFile类提供的IncreaseQuotaTo方法来申请更大的存储空间,空间的大小是用字节作为单位来表示的,如下代码片段所示,申请独立存储空间增加到5M:
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
long newQuetaSize = 5242880;
long curAvail = store.AvailableFreeSpace;
if (curAvail < newQuetaSize)
{
store.IncreaseQuotaTo(newQuetaSize);
}
}
文件被存往何处
既然独立独立存储是存放在客户端本地,那到底存放在何处呢?在我个人计算机上的地址为:C:\Documents and Settings\XXXUser\Local Settings\Application Data\Microsoft\Silverlight\is\4phkeoqx.b4f\nejnfinr.qiw\1,不同机器会有一些变化,另外在XP下的存储位置与Vista是不相同的。在g文件夹下面,我们找到当前应用程序的一些公有信息,可以看到有如下三个文件:
quota.dat记录了当前应用程序独立存储的配额,即存储空间大小
现在我们来思考一个问题,既然独立存储是一个与Cookie机制类似的局部信任机制,我们是否也可以禁用独立存储呢?答案自然是肯定的。在Silverlight应用程序上点击右键时,选择Silverlight Configuration菜单,将会看到如下窗口:
独立存储配置
最后在简单说一下独立存储配置,在Beta 1时代是应用程序配置,现在不仅支持应用程序配置,同时还支持站点配置,我们可以用它来存储应用程序配置如每个页面显示的图片数量,页面布局自定义配置等等,使用IsolatedStorageSettings类来实现,该类在设计时使用了字典来存储名-值对,它的使用相当简单:
IsolatedStorageSettings appSettings =
IsolatedStorageSettings.ApplicationSettings;
appSettings.Add("mykey","myValue");
appSettings.Save();
IsolatedStorageSettings siteSettings =
IsolatedStorageSettings.SiteSettings;
siteSettings.Add("mykey1","myValue1");
siteSettings.Save();
独立存储配置的机制与我们上面讲的一样,它也是基于本地文件存储,系统默认的会创建一个名为__LocalSettings的文件进行存储,如下图所示:
打开文件后可以看到,存储的内容(此处进行了整理)
<ArrayOfkeyvalueOfstringanyType
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<keyvalueOfstringanyType>
<Key>mykey</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema"
i:type="d3p1:string">myValue</Value>
</keyvalueOfstringanyType>
</ArrayOfkeyvalueOfstringanyType>
值得一提的是使用独立存储配置不仅仅可以存储简单类型的数据,也可以存储我们自定义类型的数据
Silverlight 4.0开始加入了System.Windows.Clipboard(剪切板操作)类,有了它我们就可以非常方便的操作剪切板的数据了,这让一些 Silverlight应用程序中的文本可以copY到Clipboard之中,同时你可以将从其它来源copY到剪切板中的内容粘贴到 Silverlight应用程序之中,在此之前我们只能通过JavaScript来访问剪切板。
接下来我们看一下Clipboard类为我们带来了什么,Clipboard类支持ContainsText、SetText和GetText三个方法,其中ContainsText可以返回一个bool类型的值,让我们知道剪切板目前保存的类型是否是Silverlight所支持的Unicode类型字符,SetText和GetText分别是用来设置和获GetText剪切板的文本数据。
下面我们看一个Silverlight操作剪切板的实例:
XAML:
1 <Grid x:Name="LayoutRoot" Width="400" Height="200" Background="White">
2 <Grid.RowDeFinitions>
3 <RowDeFinition/>
4 <RowDeFinition/>
5 </Grid.RowDeFinitions>
6 <Grid.ColumnDeFinitions>
7 <ColumnDeFinition />
8 <ColumnDeFinition Width="100"/>
9 </Grid.ColumnDeFinitions>
10 <TextBox x:Name="tbcopy" Width="260" Height="30"/>
11 <TextBox x:Name="tbPaste" Width="260" Height="30" Grid.Row="1"/>
12 <Button Content="复制" Grid.Column="1"
13 Click="btncopy_Click"
14 x:Name="btncopy" Width="80" Height="25"/>
15 <Button Content="粘贴" Grid.Column="1" Grid.Row="1"
16 Click="btnPaste_Click"
17 x:Name="btnPaste" Width="80" Height="25"/>
18 </Grid>
C#:
1 private void btncopy_Click(object sender,RoutedEventArgs e)
2 {
3 if (tbcopy.Text != string.Empty)
4 {
5 //设置剪切板
6 Clipboard.SetText(tbcopy.Text);
7 }
8 }
9
10 private void btnPaste_Click(object sender,RoutedEventArgs e)
11 {
12 //判断剪切板是否包括文本字符
13 if (Clipboard.ContainsText())
14 {
15 //获取剪切板
16 tbPaste.Text = Clipboard.GetText();
17 }
18 }
运行结果如图所示。
image
第一次运行SetText会让用户确认是否允许Silverlight操作剪切板,如果用户点击否会引发Clipboard access is not allowed异常。
image
下图完成粘贴(Paste)操作。
image
需要注意的是Silverlight与WPF不同的是,Silverlight仅仅支持Unicode字符类型的剪切板操作,还不能像WPF那像可以对不同的类型的剪切板操作,尽管如此,但是至少是Silverlight技术的一个增强,正是这种不断的进步使更多的理想在Silverlight中变为可能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。