Isolated storage in silverlight is used to store information or object therefore we don’t need to go to database to get all the information over and over again but again to use isolated storage or not should be based on case by case. Based on the implementation of the code below, I’ve found that it can compress the isolated storage file from 0.8Mb becoming 0.1 MB which is great enough for me since the quota limit is 1 mb and we try not to exceed that limit.
I’ve got this compression method from Peter Bromberg blog.
This compression method is a wrapper to SharpZip Library for Silverlight, you can download it from here, you need this library before using the code below. You can download the code below from here.
I’ve also created a Isolated Storage File with the assembly version as the file name to make sure that we have clean isolated storage file assuming the uncompressed version of isolated storage is already in production and we need to clean it up. “AssemblyVersion” properties will return the property of the current version no of the running assembly. CheckIsolatedStorageFileVersion will make sure that we always have the clean isolated storage for the new assembly.
Sample of usage
1. How to read/deserialize object from isolated storage
Dim objMessageCodes As MessageCodes = GetIsolatedStorage(Of MessageCodes)("MyFile.txt")
2. How to write/serialize object to isolated storage
Dim _messageCodes As New MessageCodes(mListMessage)
WriteIsolatedStorage(_messageCodes, "myfile.txt")
These are the definition of the above function to serialize/deserialize object from your silverlight, this function is created based on Generic so it’s flexible enough to accept anything
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.Threading
Imports System.IO
Imports System.IO.IsolatedStorage
Imports System.Xml.Serialization
Imports System.Runtime.Serialization
Imports System.Reflection
Public Class MySL
Private mAppStorage As IsolatedStorageFile
'''
''' This is used to write the compressed object to Isolated Storage
'''
'''
'''
Private Sub WriteIsolatedStorage(Of T)(ByVal obj As T, ByVal filename As String)
Try
Dim xmlByte As Byte() = Compression.SerializeAndCompress(obj)
Using _stream As IsolatedStorageFileStream = mAppStorage.CreateFile(filename)
_stream.Write(xmlByte, 0, xmlByte.Length)
End Using
Catch ex As Exception
Throw ex
End Try
End Sub
'''
''' this is used get the compressed object from Isolated storage
'''
'''
'''
'''
'''
Private Function GetIsolatedStorage(Of T)(ByVal fileName As String) As T
Try
Using _stream As IsolatedStorageFileStream = mAppStorage.OpenFile(fileName, FileMode.Open)
Using _reader As BinaryReader = New BinaryReader(_stream)
Dim tmpBytes As Byte()
ReDim tmpBytes(1024)
Dim fullBytes As Byte() = Nothing
Dim xmlStream As MemoryStream = New MemoryStream()
While True
Dim read As Integer = _reader.Read(tmpBytes, 0, tmpBytes.Length)
If (read <= 0) Then
fullBytes = xmlStream.ToArray()
Exit While
End If
xmlStream.Write(tmpBytes, 0, read)
End While
Dim xmlTempbyte As Byte() = xmlStream.ToArray()
Return Compression.DecompressAndDeserialize(Of T)(xmlTempbyte)
End Using
End Using
Return Nothing
Catch ex As Exception
Throw ex
End Try
End Function
Private _compression As Compression = Nothing
Private ReadOnly Property Compression() As Compression
Get
If (_compression Is Nothing) Then
_compression = New Compression()
End If
Return _compression
End Get
End Property
'''
''' get the assembly version
'''
'''
'''
'''
Private ReadOnly Property AssemblyVersion() As String
Get
Dim name As String = Assembly.GetExecutingAssembly().FullName
Dim asmName As AssemblyName = New AssemblyName(name)
Return asmName.Version.ToString().Replace(".", "")
End Get
End Property
'''
''' try to clear isolated storage
'''
'''
Private Sub CheckIsolatedStorageFileVersion()
Try
Dim isoStorage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForSite
If Not mAppStorage.FileExists(AssemblyVersion + ".txt") Then
'clear all the isolated storage
isoStorage.Remove()
mAppStorage.Remove()
mAppStorage = IsolatedStorageFile.GetUserStoreForApplication()
Using _stream As IsolatedStorageFileStream = mAppStorage.CreateFile(AssemblyVersion + ".txt")
Using sw As StreamWriter = New StreamWriter(_stream)
sw.Write(AssemblyVersion)
End Using
End Using
'Throw New Exception("Clearing!!!")
End If
Catch ex As Exception
Throw ex
End Try
End Sub
End Class
Wrapper Class to SL SharpZipLib
Imports System
Imports System.Text
Imports System.IO
Imports System.Collections
Imports System.Diagnostics
Imports System.Collections.Generic
Imports System.Runtime.Serialization
Imports ICSharpCode.SharpZipLib.Zip.Compression
Imports System.Xml.Serialization
Imports System.Text.RegularExpressions
Public Class Compression
Public Sub New()
End Sub
Public Function Serialize(Of T)(ByVal inst As T) As Byte()
Dim dcs As New DataContractSerializer(GetType(T))
Using ms As New MemoryStream
dcs.WriteObject(ms, inst)
Return ms.ToArray()
End Using
End Function
Public Function Deserialize(Of T)(ByVal objectData As Byte()) As T
Dim dcs As New DataContractSerializer(GetType(T))
Using ms As New MemoryStream(objectData)
Return CType(dcs.ReadObject(ms), T)
End Using
End Function
Public Function SerializeAndCompress(Of T)(ByVal inst As T) As Byte()
Dim b As Byte() = Serialize(Of T)(inst)
Return Compress(b)
End Function
Public Function DecompressAndDeserialize(Of T)(ByVal bytData As Byte()) As T
Dim bytes As Byte() = Decompress(bytData)
Return Deserialize(Of T)(bytes)
End Function
Public Function Compress(ByVal strInput As String) As Byte()
Try
Dim bytData As Byte() = System.Text.Encoding.UTF8.GetBytes(strInput)
Dim ms As New MemoryStream()
Dim defl As New Deflater(9, False)
Using s As Stream = New Streams.DeflaterOutputStream(ms, defl)
s.Write(bytData, 0, bytData.Length)
s.Close()
End Using
Return DirectCast(ms.ToArray(), Byte())
Catch
Throw
End Try
End Function
Public Function Compress(ByVal bytData As Byte()) As Byte()
Try
Dim ms As New MemoryStream()
Dim defl As New Deflater(9, False)
Using s As Stream = New Streams.DeflaterOutputStream(ms, defl)
s.Write(bytData, 0, bytData.Length)
s.Close()
End Using
Return DirectCast(ms.ToArray(), Byte())
Catch
Throw
End Try
End Function
Public Function Compress(ByVal bytData As Byte(), ByVal ParamArray ratio As Integer()) As Byte()
Dim compRatio As Integer = 9
Try
If ratio(0) > 0 Then
compRatio = ratio(0)
End If
Catch
End Try
Try
Dim ms As New MemoryStream()
Dim defl As New Deflater(compRatio, False)
Using s As Stream = New Streams.DeflaterOutputStream(ms, defl)
s.Write(bytData, 0, bytData.Length)
s.Close()
End Using
Return DirectCast(ms.ToArray(), Byte())
Catch
Throw
End Try
End Function
Public Function Decompress(ByVal bytInput As Byte()) As Byte()
Try
Dim ms As New MemoryStream(bytInput, 0, bytInput.Length)
Dim bytResult As Byte() = Nothing
Dim strResult As String = [String].Empty
Dim writeData As Byte() = New Byte(4095) {}
Using s2 As Stream = New Streams.InflaterInputStream(ms)
bytResult = ReadFullStream(s2)
s2.Close()
End Using
Return bytResult
Catch
Throw
End Try
End Function
Public Function ReadFullStream(ByVal stream As Stream) As Byte()
Dim buffer As Byte() = New Byte(32767) {}
Using ms As New MemoryStream()
While True
Dim read As Integer = stream.Read(buffer, 0, buffer.Length)
If read <= 0 Then
Return ms.ToArray()
End If
ms.Write(buffer, 0, read)
End While
End Using
Return buffer
End Function
End Class