Get up to 80 % extra points for free! More info:

Lesson 2 - Introduction to working with files

In the previous lesson, Exceptions in C# .NET, we went over exceptions, which are necessary for working with files since they allow us to react to errors properly. In today's tutorial, we're going to talk about files in general and the writing privileges in Windows. After reading this lesson, you will be ready to work with files.

Data, i.e. objects stored in memory, is lost once the application is terminated. If we want to ensure that the application data is persistent, we'd have to save it when the application is closing and load it back when we run it again. There are a lot of ways to store application data, each has some advantages and disadvantages. Generally, we store application data in one of the following ways:

  • Text files with a flat structure (e.g. .txt and .csv files)
  • Text files with an internal hierarchy (e.g. .json or .xml files)
  • Binary files (simple memory dump into a file)
  • Databases

Each data-storing method has its advantages and disadvantages. During the course, we'll explain and try them out. We'll focus mainly on how to store objects into files and load them back after the application has been terminated. Afterward, we'll move on to the database course.

Writing privileges in Windows

Windows 7 writing privileges UAC - Files and I/O in C# .NET

Since Windows Vista, Windows operating systems include what is known as UAC (User Account Control). This technology prohibits writing to the system disk partition (usually C:\) in case the writing operation is not allowed by the administrator or it's somewhere else than to the user's personal folders. This restriction obviously filled internet forums and broke many applications. However, the main thing here is that this restriction is correct and only prevents poorly written applications from changing everything they want to. Linux operating systems have had similar restrictions in order for a long time.

The Windows system concept includes user accounts. Each user account is represented by a folder (usually C:\Users\username). This folder contains, among other documents, the desktop and the so-called applications data folder. This folder can be accessed by entering the %appdata% key to the path. Type in %appdata% into the Windows explorer's path field and hit enter. You will see that many of your installed applications have subfolders in this folder. Here's where you're meant to save your applications' settings and other data. Your application will need to create its own folder here named after itself and use it to save data. Using this folder, we won't be restricted by the UAC and our application will also be able to store different settings for different users, without explicitly programming it in C#. %appdata% always points to the AppData of the user who is currently logged in.

A big mistake that people would make was that they would make their programs store their data to the folder where the program was installed. The program worked if it was saved on their desktop or on old versions of Windows. However, if it was installed into the program files folder on the C drive, it would crash with an error when writing to the disk. Windows partially emulated this sort of thing for some applications, but we won't get into that. As you may have guessed, the problem can be worked around by running the application as administrators, however, this is an improper solution.

In this tutorial, we'll create a folder for our application in the AppData folder. In other tutorials, this part won't be included so the code for various file formats is as simple as possible. If you run the application from your computer, everything should work properly. Once you publish it, however, you'll have to modify it to use AppData. Now we know where we're going to write, and we have introduced exceptions. Let's get to actually working with files!

IO and streams

In .NET, there are streams which are known as generic "data streams". We can connect to a stream and then load data from it or write data to it. Streams are theoretically universal and the same stream may lead to the RAM or to a file on the disk. Working with files is realized through streams. All of the classes that we'll mention in the future wrap a stream somehow or work with one. We don't have to work with them manually. In order to work with files we'll have to include a link to the namespace which comes with the aforementioned streams:

using System.IO;

In this course, we'll deal with one file type in each lesson and introduce a class that is designed for it. Now, let's look at the very basics of how to create a folder for our application in the current user's AppData folder. We'll use the Directory class which contains static methods for working with folders. We'll also look at the File class so we can create data (e.g. a Settings.dat file) with default values or load it. Then, to work with paths, we'll use the Path class. All three classes will be fully explained in a lesson further on in the course. For now, we're only going to introduce what is necessary. Let's write an application that will have its own folder in AppData and checks whether there is a database.dat file within said folder (don't forget to add using System.IO).

string path = "";
try
{
    path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "IctSocial");
    if (!Directory.Exists(path))
        Directory.CreateDirectory(path);
}
catch
{
    Console.WriteLine("Program failed to create a {0} folder, please check your privileges.", path);
}
if (File.Exists(Path.Combine(path, "database.dat")))
{
    try
    {
        // Place your code for loading your settings from the file here
    }
    catch (Exception e)
    {
        Console.WriteLine("Error while loading the settings: {0}", e.Message);
    }
}
else
{
    try
    {
        // Place your code for creating your settings here
    }
    catch (Exception e)
    {
        Console.WriteLine("Error while creating the settings: {0}", e.Message);
    }
}

First, we store the path to our application's folder to a path string. We get the AppData location using the following bit of code:

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

One would expect that we could simply type "%appdata%" to get it. Unfortunately, C# doesn't convert shortcuts into actual paths. GetFolderPath() will return something like this (depending on the Windows version):

C:\Users\your_name\AppData\Roaming

We'll add a folder with our application's name to the path as well. The name I chose is IctSocial, you may use your own. I didn't want us to have to check whether the paths include the trailing slash or whether the slashes should be backlashes or any of that, so we'll simply concatenate the paths using the Combine() method on the Path class. It should now look like this:

C:\Users\your_name\AppData\Roaming\IctSocial

If the given folder doesn't exist (it's the first run of the application), we'll make one. Then, we'll check whether the file whose data we want to load exists. If so, we load the data. If it doesn't, we'll create the file and save a default bit of data to it. We could also skip creating the file overall, it all depends on your application's needs.

Once we run our application, a new folder will appear in %appdata%:

The Appdata folder and creating an application folder here in C# .NET - Files and I/O in C# .NET

This was a quick introduction on how to store an application's data properly. At this point, you should be very familiar with what exceptions are as well. Now, you know all that you need to work with your first file format. In the next lesson, Working with text files in C# .NET, we'll conduct a few file operations on text files. To make things clear, I won't deal with writing privileges in future lessons so as to make keep the code simple. In other words, our programs will only work in user folders (when executed from Visual Studio). Feel free to come back here and adjust your code to fit the distributable format once you finish your application.


 

Download

By downloading the following file, you agree to the license terms

Downloaded 514x (32.72 kB)

 

Previous article
Exceptions in C# .NET
All articles in this section
Files and I/O in C# .NET
Skip article
(not recommended)
Working with text files in C# .NET
Article has been written for you by David Capka Hartinger
Avatar
User rating:
1 votes
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities