Using isolated storage for application-specific data in C# .NET Part 4: various

In the previous post we looked at how to find the location of a file when stored in isolated storage. We saw that isolated storage files have also a “normal” file path that you can navigate to in file explorer. The file paths are difficult to guess as they have complicated names but they are not secured in any way.

In this post we’ll briefly look at some various other things about isolated storage mainly related to size and quota.

Every application that uses isolated storage has a defined quota in bytes that it can use. Normally the default quota for partially trusted applications, e.g. those that you download from the internet, is 1MB. The IsolatedStorageFile object exposes a couple of properties that describe the quota, the available space and the size used:

IsolatedStorageFile applicationStorageFileForUser = IsolatedStorageFile.GetUserStoreForAssembly();
			
Debug.WriteLine(applicationStorageFileForUser.AvailableFreeSpace);
Debug.WriteLine(applicationStorageFileForUser.Quota);
Debug.WriteLine(applicationStorageFileForUser.UsedSize);

If the quota is not enough you can request a new upper limit using the IncreaseQuotaTo method of the IsolatedStorageFile class:

bool quotaIncreaseSuccess = applicationStorageFileForUser.IncreaseQuotaTo(some number);

The method will throw an exception if you’re trying to reduce the quota, i.e. set a lower number than the current quota.

Read all posts dedicated to file I/O here.

Using isolated storage for application-specific data in C# .NET Part 3: storage location

In this post we looked briefly at how to work with directories in isolated storage. In this post we’ll look at where isolated storage files are saved on disk depending on the isolation type: by user or by machine.

Recall our code to save the program settings specifically for the user:

Read more of this post

Using isolated storage for application-specific data in C# .NET Part 2: directories

In this post we briefly went through the basics of isolated storage files. We saved some applications settings in a text file within the isolated storage reserved for an application at the user level.

We’re not restricted to save files in isolated storage. We can also create folders for organisation purposes. It’s very easy to create a folder. The IsolatedStorageFileStream example is almost identical to what we saw in the post referenced above. However, remember that the directory must be created first before you can save anything in it:

private static void SaveSettingsInIsoStorage()
{
	IsolatedStorageFile applicationStorageFileForUser = IsolatedStorageFile.GetUserStoreForAssembly();
	applicationStorageFileForUser.CreateDirectory("AppSettings");
	IsolatedStorageFileStream applicationStorageStreamForUser = new IsolatedStorageFileStream("AppSettings/settings.txt", FileMode.Create, applicationStorageFileForUser);
	AppSettings settings = new AppSettings()
	{
		Job = "Programmer",
		Language = "C#",
		Name = "Andras"
	};
	string contents = JsonConvert.SerializeObject(settings);

	using (StreamWriter sw = new StreamWriter(applicationStorageStreamForUser))
	{
		sw.WriteLine(contents);
	}
}

It can be a good idea to check whether the directory exists before you create it:

string[] directoryNames = applicationStorageFileForUser.GetDirectoryNames("AppSettings");
if (!directoryNames.Any())
{
	applicationStorageFileForUser.CreateDirectory("AppSettings");
}

Read the next part here.

Read all posts dedicated to file I/O here.

Using isolated storage for application-specific data in C# .NET Part 1: the basics

There’s a special storage location for a .NET application on Windows that is allocated to that application. It’s called isolated storage and it’s an optimal place to store files by an application that doesn’t have full access to the file system. Writing to and reading from isolated storage doesn’t require any extra security check. An application without full access to the file system will be able to use its allocated slot in isolated storage and nothing else. It’s an ideal mechanism for storing e.g. application state.

However, don’t confuse isolated storage with file security. It is still a “normal” location on disk with a file path. A typical location is under users/[username]/appdata/local. Therefore you or full-trust applications can still find and modify the files saved in isolated storage. However, limited-trust applications won’t be able to access any other part of the file system.

Read more of this post

Creating temporary files on Windows using C# .NET

It’s trivial to create a temporary file using the Path class in .NET. Let’s first see how to find the path to the current user’s temp folder:

string tempFolderPath = Path.GetTempPath();

In my case it returns C:\Users\andras.nemes\AppData\Local\Temp\ which is the same as the value of the TEMP environment variable at the user level on my PC.

Read more of this post

5 ways to compress/uncompress files in .NET

There are numerous compression algorithm out there for file compression. Here come 5 examples with how-to-do links from this blog.

Compressing individual files

The following algorithms can be used to compress a single file. E.g. source.txt will be compressed to source.txt.gz.

Compressing a group of files

The following algorithms can be used to group files and then compress the file group.

Read all posts dedicated to file I/O here.

Packing and unpacking files using Tar archives in .NET

You must have come across files that were archives using the tar file format. Tar files are most often used on Unix systems like Linux but it happens that you need to deal with them in a .NET project.

You can find examples of .tar files throughout the Apache download pages, such this one. You’ll notice that .tar files are often also compressed using the GZip compression algorithm which together give the “.tar.gz” extension: they are files that were packed into a tar archive and then zipped using GZip. You can find an example of using GZip in .NET on this blog here. I have only little experience with Linux but I haven’t seen standalone “.tar” files yet, only ones that were compressed in some way. This is also the approach we’ll take in the example: pack and compress a group of files.

Tar files, as far as I know, do not compress the packaged files as opposed to zip files. So we can probably say that the Unix equivalent of .zip files are .tar.gz files. Feel free to correct these statements in the comments section if you are experienced with .tar and .tar.gz files.

Tar files are not supported in .NET out of the box but there’s a NuGet package that comes to the rescue:

sharpziplib nuget

Add this package to your .NET project. Suppose you’d like to compress the files in the c:\tar\start folder. Here’s a compact code example:

DirectoryInfo directoryOfFilesToBeTarred = new DirectoryInfo(@"c:\tar\start");
FileInfo[] filesInDirectory = directoryOfFilesToBeTarred.GetFiles();
String tarArchiveName = @"c:\tar\mytararchive.tar.gz";
using (Stream targetStream = new GZipOutputStream(File.Create(tarArchiveName)))
{
	using (TarArchive tarArchive = TarArchive.CreateOutputTarArchive(targetStream, TarBuffer.DefaultBlockFactor))
	{
		foreach (FileInfo fileToBeTarred in filesInDirectory)
		{
			TarEntry entry = TarEntry.CreateEntryFromFile(fileToBeTarred.FullName);
			tarArchive.WriteEntry(entry, true);
		}
	}
}

Note that other compression types such as Bzip2 and DEFLATE are available in the SharpZipLib library:

using (Stream targetStream = new BZip2OutputStream(File.Create(tarArchiveName), 9)) 
.
.
.
using (Stream targetStream = new DeflaterOutputStream(File.Create(tarArchiveName)))

We can then unpack the tar archive as follows:

FileInfo tarFileInfo = new FileInfo(@"c:\tar\mytararchive.tar.gz");
DirectoryInfo targetDirectory = new DirectoryInfo(@"c:\tar\finish");
if (!targetDirectory.Exists)
{
	targetDirectory.Create();
}
using (Stream sourceStream = new GZipInputStream(tarFileInfo.OpenRead()))
{
	using (TarArchive tarArchive = TarArchive.CreateInputTarArchive(sourceStream, TarBuffer.DefaultBlockFactor))
	{
		tarArchive.ExtractContents(targetDirectory.FullName);
	}				
}

Read all posts dedicated to file I/O here.

Packing and unpacking files using Zip archives in .NET

We’ve looked at a couple of (de)compression techniques available in .NET in previous posts, see link below. Here we’ll look at how to compress multiple files into well-known ZIP files using .NET.

.NET4.5 has added native support for ZIP files, though you need to add the following library to reach the new functions:

New system compression dll

Say you’d like to compress all files within a folder:

DirectoryInfo filesToBeZipped = new DirectoryInfo(@"c:\zip\start");
FileInfo zipFileName = new FileInfo(@"c:\zip\zipped.zip");
ZipFile.CreateFromDirectory(filesToBeZipped.FullName, zipFileName.FullName);

…and this how you can unzip it:

DirectoryInfo extractTo = new DirectoryInfo(@"c:\zip\unzip");
ZipFile.ExtractToDirectory(zipFileName.FullName, extractTo.FullName);

The above code examples will zip and unzip all files in the directory. However, there are times when you’d like to access the individual files in the ZIP archive or add new files to an existing zip file. For this you’ll need to add one more library reference:

New system compression dll for zip archive

The following code will create the zip file and then look at each archived file one by one. If a file is larger than a certain limit then it’s extracted to a special folder:

DirectoryInfo filesToBeZipped = new DirectoryInfo(@"c:\zip\start");
FileInfo zipFileName = new FileInfo(@"c:\zip\zipped.zip");
ZipFile.CreateFromDirectory(filesToBeZipped.FullName, zipFileName.FullName);
DirectoryInfo extractTo = new DirectoryInfo(@"c:\zip\unzip_individual");
if (!extractTo.Exists)
{
	extractTo.Create();
}
using (ZipArchive zipArchive = ZipFile.OpenRead(zipFileName.FullName))
{
	foreach (ZipArchiveEntry zipArchiveEntry in zipArchive.Entries)
	{
		Console.WriteLine(zipArchiveEntry.FullName);
		if (zipArchiveEntry.Length > 100)
		{
			zipArchiveEntry.ExtractToFile(Path.Combine(extractTo.FullName, zipArchiveEntry.FullName));
		}
	}
}

Here’s how you can add a existing file to an existing ZIP archive:

FileInfo zipFileName = new FileInfo(@"c:\zip\zipped.zip");
FileInfo newFileToBeAdded = new FileInfo(@"c:\temp\result.txt");
using (FileStream zipToBeExtended = new FileStream(zipFileName.FullName, FileMode.Open))
{
	using (ZipArchive zipArchive = new ZipArchive(zipToBeExtended, ZipArchiveMode.Update))
	{
		ZipArchiveEntry newEntry = zipArchive.CreateEntryFromFile(newFileToBeAdded.FullName, "result-zipped.txt");
	}
}

This code will add “newFileToBeAdded” to the existing zip archive and name it “result-zipped.txt”.

You can also create a new zip archive entry and add content to it on the fly:

FileInfo zipFileName = new FileInfo(@"c:\zip\zipped.zip");
using (FileStream zipToBeExtended = new FileStream(zipFileName.FullName, FileMode.Open))
{
	using (ZipArchive zipArchive = new ZipArchive(zipToBeExtended, ZipArchiveMode.Update))
	{
		ZipArchiveEntry newZipEntryOnTheFly = zipArchive.CreateEntry("new-result.txt");
		using (StreamWriter streamWriter = new StreamWriter(newZipEntryOnTheFly.Open()))
		{
			streamWriter.WriteLine("Hello from the brand new zip archive entry!");
		}
	}
}

Read all posts dedicated to file I/O here.

Compressing and decompressing files with BZip2 in .NET C#

BZip2 is yet another data compression algorithm, similar to GZip and Deflate. There’s no native support for BZip2 (de)compression in .NET but there’s a NuGet package provided by icsharpcode.net.

You’ll need to import the following NuGet package to use BZip2:

sharpziplib nuget

You can compress a file as follows:

FileInfo fileToBeZipped = new FileInfo(@"c:\bzip2\logfile.txt");
FileInfo zipFileName = new FileInfo(string.Concat(fileToBeZipped.FullName, ".bz2"));
using (FileStream fileToBeZippedAsStream = fileToBeZipped.OpenRead())
{
	using (FileStream zipTargetAsStream = zipFileName.Create())
	{
		try
		{
			BZip2.Compress(fileToBeZippedAsStream, zipTargetAsStream, true, 4096);
		}
		catch (Exception ex)
		{
			Console.WriteLine(ex.Message);
		}
	}
}

…and this is how you can decompress the resulting bz2 file again:

using (FileStream fileToDecompressAsStream = zipFileName.OpenRead())
{
	string decompressedFileName = @"c:\bzip2\decompressed.txt";
	using (FileStream decompressedStream = File.Create(decompressedFileName))
	{
		try
		{
			BZip2.Decompress(fileToDecompressAsStream, decompressedStream, true);
		}
		catch (Exception ex)
		{
			Console.WriteLine(ex.Message);
		}
	}
}

Read all posts dedicated to file I/O here.

How to compress and decompress files with Deflate in .NET C#

We saw the usage of the GZipStream object in this post. GZipStream follows the GZip compression algorithm which is actually based on DEFLATE and includes some headers. As a result GZip files are somewhat bigger than DEFLATE files.

Just like with GZip, DEFLATE compresses a single file and does not hold multiple files in a zip archive fashion. It is represented by the DeflateStream object and is used in much the same way as a GZipStream. The example code is in fact almost identical.

This is how to compress a file:

FileInfo fileToBeDeflateZipped = new FileInfo(@"c:\deflate\logfile.txt");
FileInfo deflateZipFileName = new FileInfo(string.Concat(fileToBeDeflateZipped.FullName, ".cmp"));

using (FileStream fileToBeZippedAsStream = fileToBeDeflateZipped.OpenRead())
{
	using (FileStream deflateZipTargetAsStream = deflateZipFileName.Create())
	{
		using (DeflateStream deflateZipStream = new DeflateStream(deflateZipTargetAsStream, CompressionMode.Compress))
		{
			try
			{
				fileToBeZippedAsStream.CopyTo(deflateZipStream);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
			}
		}
	}
}

…and here’s how you can decompress a file:

using (FileStream fileToDecompressAsStream = deflateZipFileName.OpenRead())
{
	string decompressedFileName = @"c:\deflate\decompressed.txt";
	using (FileStream decompressedStream = File.Create(decompressedFileName))
	{
		using (DeflateStream decompressionStream = new DeflateStream(fileToDecompressAsStream, CompressionMode.Decompress))
		{
			try
			{
				decompressionStream.CopyTo(decompressedStream);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
			}
		}
	}
}

Read all posts dedicated to file I/O here.

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

ARCHIVED: Bite-size insight on Cyber Security for the not too technical.