Isolated storage is simple to use and requires knowledge of
relatively few classes. The most important class is
System.IO.IsolatedStorage.IsolatedStorageFile.
IsolatedStorageFile objects represent individual
stores and provide methods to manage the files and
directories contained within the stores, as well as properties to
access information, such as the store's isolation
scope, current size, and maximum size. The
IsolatedStorageFile class also provides static
factory methods through which you initially obtain store objects.
Also important is the
System.IO.IsolatedStorage.IsolatedStorageFileStream
class, which extends System.IO.FileStream and
provides the mechanism through which you
read and write data to files in isolated storage.
In the following sections, we demonstrate how to use these classes to
implement the use of isolated storage in your programs. First, we
look at the code-access permissions used to control access to
isolated storage.
1. Isolated Storage and Code-Access Security
The
System.Security.Permissions.IsolatedStorageFilePermission
code-access permission class controls access to
isolated
storage. Unlike the
System.Security.Permissions.FileIOPermission class
that controls direct access to the hard drive, the
IsolatedStorageFilePermission class does not
control the type of access (read or write) to specific directories or
even specific stores.
IsolatedStorageFilePermission controls access to
isolated storage by restricting the scope of isolation at which code
can obtain a store. Permission to obtain a store of a specified scope
implies the ability for code to read and write data in the store. The
IsolatedStorageFilePermission class also controls
the maximum size that code can make a store.
If different code obtains the same store, the maximum store size
granted to each assembly may be different based on the configuration
of the IsolatedStorageFilePermission granted to
the each assembly.
|
|
When configuring IsolatedStorageFilePermission
instances, the
System.Security.Permissions.IsolatedStorageContainment
enumeration represents the different isolation
scopes available, as well as some levels of access that transcend the
individual isolation scopes. Table 1 lists the
members of the IsolatedStorageContainment
enumeration and describes the access they represent.
Table 1. Members of the IsolatedStorageContainment enumeration
Member
|
Description
|
---|
None
|
No permission to access isolated storage
|
DomainIsolationByUser
|
Permission to obtain a nonroaming store isolated by user, assembly,
and application domain
|
AssemblyIsolationByUser
|
Permission to obtain a nonroaming store isolated by user and assembly
|
DomainIsolationByRoamingUser
|
Permission to obtain a roaming store isolated by user, assembly, and
application domain
|
AssemblyIsolationByRoamingUser
|
Permission to obtain a roaming store isolated by user and assembly
|
AdministerIsolatedStorageByUser
|
Permission to enumerate and obtain all stores for the current user,
but not the ability to modify the stores contents
|
UnrestrictedIsolatedStorage
|
Grants code unrestricted access to all stores isolated by the current
user
|
The IsolatedStorageFilePermission treats the
DomainIsolationByUser,
AssemblyIsolationByUser,
DomainIsolationByRoamingUser, and
AssemblyIsolationByRoamingUser values of the
IsolatedStorageContainment enumeration as a
hierarchy of permissions. This introduces an important inconsistency
in the control of access to isolated storage. Granting code the
DomainIsolationByRoamingUser permission results in
the code also obtaining a store isolated by user and assembly
(AssemblyIsolationByUser) only. This introduces a
significant risk because an assembly used by multiple applications
can leak data between those applications, when the expected behavior
allows code to obtain a roaming store isolated by user, assembly, and
application domain.
|
|
Despite the relative safety of isolated storage,
.NET's default security policy restricts the isolation scope of stores some
code can obtain. In particular, code run from the Internet can obtain
only a store isolated by user, assembly, and application domain. This
minimizes the chance that applications downloaded from the Internet
can share data between each other.
If you intend to use isolated storage
in your code, it is prudent to use a
permission request, to ensure the runtime grants your code the
isolation scope it requires. The following code demonstrates the
statements that request permission to create stores of some sample
isolation scopes:
# C#
// Minimum permission request to obtain a non-roaming store isolated by
// user, assembly, and application domain
[assembly:IsolatedStorageFilePermission(SecurityAction.RequestMinimum,
UsageAllowed = IsolatedStorageContainment.DomainIsolationByUser)]
// Minimum permission request to obtain a roaming store isolated by
// user and assembly with a quota of 2048 bytes
[assembly:IsolatedStorageFilePermission(SecurityAction.RequestMinimum,
UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByRoamingUser,
UserQuota = 2048)]
// Minimum permission request for unrestricted access to isolated storage
[assembly:IsolatedStorageFilePermission(SecurityAction.RequestMinimum,
Unrestricted = true)]
# Visual Basic .NET
' Minimum permission request to obtain a non-roaming store isolated by
' user, assembly, and application domain
<Assembly:IsolatedStorageFilePermission(SecurityAction.RequestMinimum, _
UsageAllowed := IsolatedStorageContainment.DomainIsolationByUser)>
' Minimum permission request to obtain a roaming store isolated by
' user and assembly with a quota of 2048 bytes
<Assembly:IsolatedStorageFilePermission(SecurityAction.RequestMinimum, _
UsageAllowed:=IsolatedStorageContainment.AssemblyIsolationByRoamingUser, _
UserQuota := 2048)>
' Minimum permission request for unrestricted access to isolated storage
<Assembly:IsolatedStorageFilePermission(SecurityAction.RequestMinimum, _
Unrestricted := true)>
You cannot Assert the
IsolatedStorageFilePermission in your code;
attempts to Assert are ignored.
|
|
2. Obtaining a Store
Two static methods of the IsolatedStorageFile
class provide the
simplest and most common way of obtaining a store:
GetUserStoreForAssembly
-
Returns a nonroaming store isolated by
user and assembly. To invoke
GetUserStoreForAssembly, the calling code must
have the AssemblyIsolationByUserIsolatedStorageFilePermission permission.
element of the
GetUserStoreForDomain
-
Returns a nonroaming store isolated
by
user, assembly, and application domain.
To invoke GetUserStoreForDomain, the calling code
must have the DomainIsolationByUser element of the
IsolatedStorageFilePermission permission.
Both methods take no arguments and return an
IsolatedStorageFile object representing the store
with the appropriate identity for the current user and code. If a
store with the necessary identity does not already exist, isolated
storage creates a new one. The following statements demonstrate the
use of both methods:
# C#
// Obtain a store isolated by user and assembly
IsolateStorageFile iso1 = IsolatedStorageFile.GetUserStoreForAssembly( );
// Obtain a store isolated by user, assembly, and application domain
IsolateStorageFile iso2 = IsolatedStorageFile.GetUserStoreForDomain( );
# Visual Basic .NET
' Obtain a store isolated by user and assembly
Dim iso1 As IsolateStorageFile =_
IsolatedStorageFile.GetUserStoreForAssembly( )
' Obtain a store isolated by user, assembly, and application domain
Dim iso2 As IsolateStorageFile = _
IsolatedStorageFile.GetUserStoreForDomain( )
The static IsolatedStorageFile.GetStore method
also obtains
a store, but allows the caller to specify the scope and identity of
the store to obtain. GetStore has three overloads
that provide different ways to specify the identity of the store. We
show the most commonly used signature here; refer to the .NET
Framework documentation for a discussion of all available overloads:
# C#
public static IsolatedStorageFile GetStore {
IsolatedStorageScope scope,
object domainIdentity,
object assemblyIdentity
);
# Visual Basic .NET
Overloads Public Shared Function GetStore( _
ByVal scope As IsolatedStorageScope, _
ByVal domainIdentity As Object, _
ByVal assemblyIdentity As Object _
) As IsolatedStorageFile
The domainIdentity and
assemblyIdentity arguments represent the evidence
objects for isolated storage to use when determining the identity of
the store to obtain. Specifying null (C#) or
Nothing (Visual Basic .NET) for both arguments
means isolated storage will use its default approach to determine
code identity.
The scope argument takes a value of the
System.IO.IsolatedStorage.IsolatedStorageScope
enumeration that identifies the desired isolation scope for the
store. The IsolatedStorageScope enumeration
contains the following five values:
Assembly
Domain
None
Roaming
User
By themselves, these values serve no purpose; only by combining them
using a logical Or operation do they have any
meaning to the GetStore method. Table 2 lists the valid combination of values. The |
symbol is the C# equivalent of the Visual Basic .NET Keyword
Or.
Table 2. Valid IsolatedStorageScope values for GetStore
Values
|
Description
|
---|
User | Assembly
|
Requests a store isolated by user and assembly, the same as that
returned by the GetUserStoreForAssembly method
|
User | Assembly |
Domain
|
Requests a store isolated by user, assembly, and application domain,
the same as that returned by the
GetUserStoreForDomain method
|
Roaming | User |
Assembly
|
Requests a roaming store isolated by user and assembly
|
Roaming | User |
Assembly | Domain
|
Requests a roaming store isolated by user, assembly, and application
domain
|
GetStore is the only way to obtain stores backed
by Windows-roaming profiles. If you use
GetUserStoreForAssembly,
GetUserStoreForDomain, or do not specify the
Roaming flag when calling
GetStore, the store will exist only on the machine
on which it was created and will not be accessible to the user when
she uses other machines.
Because the GetStore method allows you to override
the default evidence used to identify the store to obtain, you can
obtain another application's store if you specify
the correct evidence values—a relatively easy task. This breaks
the normal code-level isolation provided by isolated storage;
therefore, the calling code must have the more highly trusted
AdministerIsolatedStorageByUser element of the
IsolatedStorageFilePermission to call
GetStore with evidence arguments that are not
null (C#) or Nothing (Visual
Basic .NET).
The following statements demonstrate the use of the
GetStore method, including method calls that are
equivalent to calling the GetUserStoreForAssembly
and GetUserStoreForDomain methods:
# C#
// GetStore equivalent of GetUserStoreForAssembly
IsolatedStorageFile iso1 = IsolatedStorageFile.GetStore(
IsolatedStorageScope.User | IsolatedStorageScope. Assembly,
null, null
);
// GetStore equivalent of GetUserStoreForDomain
IsolatedStorageFile iso2 = IsolatedStorageFile.GetStore(
IsolatedStorageScope.User | IsolatedStorageScope.Assembly |
IsolatedStorageScope.Domain, null, null
);
// Get a roaming store isolated by user and assembly. Specify
// new Url evidence for the assembly identity
IsolatedStorageFile iso3 = IsolatedStorageFile.GetStore(
IsolatedStorageScope.User | IsolatedStorageScope.Assembly |
IsolatedStorageScope.Roaming, null, new Url(@"http://test.com")
);
# Visual Basic .NET
' GetStore equivalent of GetUserStoreForAssembly
Dim iso1 As IsolatedStorageFile = IsolatedStorageFile.GetStore( _
IsolatedStorageScope.User Or IsolatedStorageScope.Assembly, _
Nothing, Nothing)
' GetStore equivalent of GetUserStoreForDomain
Dim iso2 As IsolatedStorageFile = IsolatedStorageFile.GetStore( _
IsolatedStorageScope.User Or IsolatedStorageScope.Assembly Or _
IsolatedStorageScope.Domain, Nothing, Nothing)
' Get a roaming store isolated by user and assembly. Specify
' new Url evidence for the assembly identity
Dim iso3 As IsolatedStorageFile = IsolatedStorageFile.GetStore( _
IsolatedStorageScope.User Or IsolatedStorageScope.Assembly Or _
IsolatedStorageScope.Roaming, Nothing, New Url("http://test.com"))
The final way to obtain a store is to enumerate all stores for the
current user. This breaks the data isolation provided by isolated
storage completely and requires the caller to have the
AdministerIsolatedStorageByUser element of the
IsolatedStorageFilePermission permission. The
IsolatedStorageFile.GetEnumerator method has the
following signature:
# C#
public static IEnumerator GetEnumerator(
IsolatedStorageScope scope
);
# Visual Basic .NET
Public Shared Function GetEnumerator( _
ByVal scope As IsolatedStorageScope _
) As IEnumerator
The scope argument takes a value of the
IsolatedStorageScope enumeration; Table 3 lists the valid member combinations.
Table 3. Valid IsolatedStorageScope values for GetEnumerator
Values
|
Description
|
---|
User
|
Returns an enumeration across all nonroaming stores for the current
user
|
Roaming | User
|
Returns an enumeration across all roaming stores for the current user
|
You can read data from IsolatedStorageFile objects
obtained through the GetEnumerator method, but you
cannot write to them. Methods that write data to stores ensure that
no write operation increases the size of the store beyond that
specified by the IsolatedStorageFilePermission
permission granted to the executing code. When code obtains a store
through the GetStore,
GetUserStoreForAssembly, or
GetUserStoreForDomain methods, the
code's permissions determine the maximum size of the
store. This figure is stored in the
IsolatedStorageFile.MaximumSize property. However,
code that executes GetEnumerator has no defined
quota and so no maximum size is set. The lack of a maximum size value
does not, however, result in an unrestricted store quote. Any attempt
by code that obtains a store using GetEnumerator
to read or modify the MazimumSize property will
cause a System.InvalidOperationException to be
thrown.
Example 1 demonstrates the use of the
GetEnumerator method to obtain all nonroaming
stores for the current user. We then step through the stores and
display the stores' isolation scope, current size,
and the evidence of the code that created the stores using the
Scope, CurrentSize,
AssemblyIdentity, and
DomainIdentity properties:
Example 1. Enumerating and displaying the characteristics of isolated stores
# C#
using System; using System.Collections; using System.IO.IsolatedStorage; using System.Security.Permissions;
// Ensure we have permission to enumerate stores [assembly:IsolatedStorageFilePermission(SecurityAction.RequestMinimum, UsageAllowed = IsolatedStorageContainment.AdministerIsolatedStorageByUser)]
public class EnumerateStores {
public static void Main( ) { // Obtain an IEnumerator across all non roaming stores for the // current user IEnumerator e = IsolatedStorageFile.GetEnumerator(IsolatedStorageScope.User); // Iterate through the enumerator while (e.MoveNext( )) { IsolatedStorageFile i = (IsolatedStorageFile)e.Current; // Display the scope of the current store Console.WriteLine("STORE SCOPE: {0}", i.Scope); // Display the maximum and current size for the store Console.WriteLine("Current size={0}", i.CurrentSize); // Display the assembly identity of the current store Console.WriteLine("Assembly ID:"); Console.WriteLine(i.AssemblyIdentity); // Display the domain identity of the current store if // the store is isolated by domain if ((i.Scope & IsolatedStorageScope.Domain) != 0) { Console.WriteLine("Domain ID:"); Console.WriteLine(i.DomainIdentity); } } } } # Visual Basic .NET
Imports System Imports System.Collections Imports System.IO.IsolatedStorage Imports System.Security.Permissions ' Ensure we have permission to enumerate stores <assembly:IsolatedStorageFilePermission(SecurityAction.RequestMinimum, _ UsageAllowed := IsolatedStorageContainment.AdministerIsolatedStorageByUser _ )> _ Public Class EnumerateStores Public Shared Sub Main( ) ' Obtain an IEnumerator across all non roaming stores for the ' current user Dim e As IEnumerator = _ IsolatedStorageFile.GetEnumerator(IsolatedStorageScope.User) ' Iterate through the enumerator While e.MoveNext( ) Dim i As IsolatedStorageFile = _ CType(e.Current, IsolatedStorageFile) ' Display the scope of the current store Console.WriteLine("STORE SCOPE: {0}", i.Scope) ' Display the maximum and current size for the store Console.WriteLine("Current size={0}", i.CurrentSize) ' Display the assembly identity of the current store Console.WriteLine("Assembly ID:") Console.WriteLine(i.AssemblyIdentity) ' Display the domain identity of the current store if ' the store is isolated by domain If (i.Scope And IsolatedStorageScope.Domain) <> 0 Then Console.WriteLine("Domain ID:") Console.WriteLine(i.DomainIdentity) End If End While End Sub End Class
|
3. Creating Directories
Once you have an IsolatedStorageFile object
representing a store, you can create files and
directories in the store. .NET's isolated storage
implementation does not provide an object that represents
directories; this simplifies the isolated storage class structure but
also forces you to constantly work with strings that represent
directory paths. The CreateDirectory method, with
the
following signature, creates a directory with the specified fully
qualified name:
# C#
public void CreateDirectory(
string dir
);
# Visual Basic .NET
Public Sub CreateDirectory( _
ByVal dir As String _
)
You can create more than one level of the directory hierarchy in a
single call. For example, the following statements create a directory
named Dir1, as well as two subdirectories named
Dir2 and Dir3 in the store
represented by the iso object:
# C#
IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForDomain( );
iso.CreateDirectory(@"Dir1\Dir2");
iso.CreateDirectory("Dir1/Dir3");
# Visual Basic .NET
Dim iso As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForDomain( )
iso.CreateDirectory("Dir1\Dir2")
iso.CreateDirectory("Dir1/Dir3")
On the first call, CreateDirectory creates both
the Dir1 and Dir2 directories.
If you specify a directory name that already exists, as is the case
with Dir1 in the second call to
CreateDirectory, no error occurs. If you specify a
directory name that contains illegal characters,
CreateDirectory throws an
IsolatedStorageException. As this code shows, you
can use either the forward slash / or backward slash \ characters as
the path separators.
4. Creating, Reading, and Writing Files
The IsolatedStorageFileStream class represents a
file in a store.
IsolatedStorageFileStream extends
System.IO.FileStream and apart
from its Handle
property, supports all of the normal file I/O capabilities that you
are familiar with, including asynchronous I/O. If you use the
Handle property, it throws
an
IsolatedStorageException.
You do not create an IsolatedStorageFileStream
through an IsolatedStorageFile object as you may
expect; instead, you pass the
IsolatedStorageFile instance in which you want to
create or open the file to one of the
IsolatedStorageFileStream constructors. The
IsolatedStorageFileStream class provides eight
overloaded constructors. We show the most specific
IsolatedStorageFileStream constructor signature
here; the other seven variations take subsets of the arguments
required by this version and provide defaults for the arguments not
specified:
# C#
public IsolatedStorageFileStream(
string path,
FileMode mode,
FileAccess access,
FileShare share,
int bufferSize,
IsolatedStorageFile isf
);
# Visual Basic .NET
Public Sub New( _
ByVal path As String, _
ByVal mode As FileMode, _
ByVal access As FileAccess, _
ByVal share As FileShare, _
ByVal bufferSize As Integer, _
ByVal isf As IsolatedStorageFile _
)
All of the arguments to the
IsolatedStorageFileStream constructor serve the
same purpose as those to the FileStream
constructor, and we do not cover them in detail here. Of special
interest are the first and last arguments: path
and isf. The path argument is a
String that contains the name of the file to
create and must include the full path (within the store) of the file.
If you create a file in a directory, the directory must exist before
you create the file. The isf argument
is a reference to the
IsolatedStorageFile in which to create or open the
file.
Some constructors of the IsolatedStorageFileStream
class do not require you to obtain an
IsolateStorageFile object first. When you call
them, they automatically open a store isolated by user, assembly, and
application domain as if you had first called the
GetUserAssemblyForDomain method. Refer to the .NET
Framework SDK documentation for details on the available
constructors.
|
|
After creating or opening a file in a store, you can use the
IsolatedStorageFileStream object as you would with
any other FileStream object. Example 2 demonstrates two methods that demonstrate the
simplicity with which you can read and write XML data to isolated
storage—a common approach when storing user and application
data. In WriteConfig, we demonstrate the creation
of an XML file named Config.xml, to which we
write the contents of a System.Xml.XmlDocument. In
the ReadConfig method, read the
Config.xml file and return a new
XmlDocument created from the files contents.
Consult the .NET Framework SDK documentation for details of the
XmlDocument class.
Example 2. Reading and writing XML data to isolated storage
# C#
public static void WriteConfig(IsolatedStorageFile store, XmlDocument xml) {
//Ensure there is a config directory store.CreateDirectory("/config"); // Create or Open the Config.xml file IsolatedStorageFileStream str = new IsolatedStorageFileStream( "/config/Config.xml", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 100, store ); // Write the XmlDocument to the isolated storage file xml.Save(str);
// Close the Config.xml file str.Close( ); }
public static XmlDocument ReadConfig(IsolatedStorageFile store) { // Open the Config.xml file IsolatedStorageFileStream str = new IsolatedStorageFileStream( "config/Config.xml", FileMode.Open, FileAccess.Read, FileShare.None, 100, store ); // Create a new XmlDocument and load the config file XmlDocument xml = new XmlDocument( ); xml.Load(str); // Close the Config.xml file str.Close( ); // return the XmlDocument return xml; }
# Visual Basic .NET
Public Shared Sub WriteConfig(ByVal store As IsolatedStorageFile, _ ByVal xml As XmlDocument)
'Ensure there is a config directory store.CreateDirectory("/config")
' Create or Open the Config.xml file Dim str As IsolatedStorageFileStream = New IsolatedStorageFileStream( _ "/config/Config.xml",FileMode.OpenOrCreate,FileAccess.Write, _ FileShare.None,100,store)
' Write the XmlDocument to the isolated storage file xml.Save(str)
' Close the Config.xml file str.Close( ) End Sub
Public Shared Function ReadConfig(ByVal store As IsolatedStorageFile) _ As XmlDocument
' Open the Config.xml file Dim str As IsolatedStorageFileStream = New IsolatedStorageFileStream( _ "config/Config.xml",FileMode.Open,FileAccess.Read,FileShare.None,100, _ store)
' Create a new XmlDocument and load the config file Dim xml As XmlDocument = New XmlDocument( ) xml.Load(str)
' Close the Config.xml file str.Close( )
' return the XmlDocument Return xml End Function
|
5. Searching for Files and Directories
Isolated storage does not provide
any mechanism through which
you can work directly with objects that represent the individual
directories within a store, but does provide search capabilities that
simplify the discovery of files and directories.
The GetDirectoryNames and
GetFileNames methods
both return a String
array containing a list of files or directories contained in a store
with names that match a specified pattern. Both methods take a single
String argument containing the pattern for which
to search. The GetDirectoryNames and
GetFileNames methods have the following
signatures:
# C#
public string[] GetDirectoryNames(
string searchPattern
);
public string[] GetFileNames(
string searchPattern
);
# Visual Basic .NET
Public Function GetDirectoryNames( _
ByVal searchPattern As String _
) As String( )
Public Function GetFileNames( _
ByVal searchPattern As String _
) As String( )
The searchPattern argument must specify the full
path of the directory in which you want to search and can include
both single-character ("?") and
multicharacter ("*") wildcards, but
only in the final element. Table 4 lists some
example values of searchPattern for both the
GetDirectoryNames and
GetFileNames methods and describes their effects.
Table 4. Example searchPattern values
Values
|
Description
|
---|
GetDirectoryNames
| |
"*"
|
Returns the names of all directories contained in the root directory
|
"/data/*"
|
Returns the names of all directories contained in the data directory
|
"/data??/*"
|
Error; wildcards can occur only in the last element
|
GetFileNames
| |
"*"
|
Returns the names of all files contained in the root directory
|
"config/*.xml"
|
Returns the names of all .xml files contained in
the config directory
|
"data/SomeApp.???"
|
Returns the names of all files in the data directory with the name SomeApp and any three-letter extension
|
We demonstrate the use of both the
GetDirectoryNames and
GetFileNames methods in the following section.
6. Deleting Files and Directories
You delete files and directories from a store through the
methods of the IsolatedStorageFile object that
represents the containing store. Both the
DeleteDirectory and DeleteFile
methods take a single String argument that
specifies the fully qualified name of the file to delete:
# C#
public void DeleteDirectory(
string dir
);
public void DeleteFile(
string file
);
# Visual Basic .NET
Public Sub DeleteDirectory( _
ByVal dir As String _
)
Public Sub DeleteFile( _
ByVal file As String _
)
If you try to delete a directory that does not exist or you include
wildcard characters in the directory name,
DeleteDirectory throws an
IsolatedStorageFile exception. Attempting to
delete a file that does not exist also results in an
IsolatedStorageFile exception, but including
wildcard characters in the filename will cause a
System.Argument exception.
The major difficulty in using DeleteDirectory is
that the directory must be empty of files and subdirectories before
you can delete it. Because you cannot specify wildcard characters to
delete groups of files and directories, you have to implement the
program logic necessary to delete all of the files in the directory.
Example 3 contains a static method named
DeleteDirectory, which demonstrates the techniques
necessary to delete an isolated storage directory tree.
DeleteDirectory takes two arguments: an
IsolatedStorageFile object that represents the
store containing the directory to delete, and a
System.String, which specifies the fully qualified
name of the directory to delete—for example,
"/config/gary":
Example 3. Deleting an isolated storage directory tree
# C#
public static void DeleteDirectory(IsolatedStorageFile store, String root) { // Ensure we have a directory name ending in a "/" character String dir = root.EndsWith("/") ? root : root + "/"; // Get a list of all files in the current directory, iterate // through them and delete them. foreach (String file in store.GetFileNames(dir + "*")) { store.DeleteFile(file); }
// Get a list of all sub-directories in the current directory, // iterate through them and delete them. foreach (String subdir in store.GetDirectoryNames(dir + "*")) { DeleteDirectory(store, dir + subdir + "/"); } // Delete the current directory store.DeleteDirectory(dir); }
# Visual Basic .NET
Public Shared Sub DeleteDirectory(ByVal store As IsolatedStorageFile, _ ByVal root As String)
' Ensure we have a directory name ending in a "/" character Dim dir As String = IIf(root.EndsWith("/"), root, root & "/")
' Get a list of all files in the current directory, iterate ' through them and delete them. Dim file As String For Each file In store.GetFileNames(dir + "*")
store.DeleteFile(file) Next
' Get a list of all sub-directories in the current directory, ' iterate through them and delete them. Dim subdir As String For Each subdir In store.GetDirectoryNames(dir + "*")
DeleteDirectory(store, dir + subdir + "/") Next
' Delete the current directory store.DeleteDirectory(dir) End Sub
|
7. Deleting Stores
To delete a store, use the Remove method of
the
IsolatedStorageFile class.
Remove has two overloads, with the signatures
shown here:
# C#
public override void Remove( );
public static void Remove(
IsolatedStorageScope scope
);
# Visual Basic .NET
Overrides Overloads Public Sub Remove( )
Overloads Public Shared Sub Remove( _
ByVal scope As IsolatedStorageScope _
)
The first overload is an instance method that takes no arguments and
simply deletes the store represented by the current
IsolatedStorageFile object. If you try to use the
IsolatedStorageFile object after calling
Remove, a
System.InvalidOperation exception is thrown
because the store is considered to be closed. The second
Remove overload is a static method that takes an
IsolatedStorageScope argument, which represents
the isolation scope of the stores to delete. Table 5 lists the valid combination of
IsolatedStorageScope values you can use for the
scope argument.
Once you delete a store, its contents are not recoverable.
|
|
Table 5. Valid IsolatedStorageScope values for GetEnumerator
Values
|
Description
|
---|
User
|
Removes all nonroaming stores for the current user
|
Roaming | User
|
Removes all roaming stores for the current user
|