Archive

Archive for December, 2008

Building a website the Big Brother way: The logo

December 31, 2008 scerrimark 1 comment

Hello hope you are OK!! So let’s get straight to work. In my previous post I said that we were going to create a web layout with Photoshop. However my client said that he also needed a new logo (first change in requirements: get used to it ;) ). So in this post I will tell you how I am going to create a logo using Photoshop. I hope you have downloaded Photoshop and experimented a bit with it. If not download it from here (30 day trial version).

Now before we start the design of the logo we need to think of a colour scheme that we are going to apply to the website. Choosing a colour scheme is no easy task becuase it depends on the aim and scope of the website/logo. However in this case the client already has a colour scheme that he used in his old logo and that he wishes to retain. According to the client this is “black and gold”. Now he wants a new logo “something more modern”. Therefore I came up with the following colour scheme:

1e2528

Color HEX: 1e2528

6a7378

Color HEX: 6a7378

ffffff

Color HEX: ffffff

cfb52b1

Color HEX: cfb52b

So if you observed well our colour scheme (or palette) does not contain black but a dark colour very similar to black with a hex value of 1e2528 (we are using hex values because of photoshop). This gives a more modern look and feel. These will be the four colours that we will use in both the logo and the web layout. So let’s start straight away with the logo. Open up Adobe Photoshop CS4.

Now to help you with this tutorial the image below is the finished logo. The reason why I am going to show you the finished logo is because it will help you more understand what is going on in this tutorial. Here it is!

logo

So let’s start step by step. Now that you have Photoshop open go to File menu and choose New (alternatively use the shortcut Ctrl+N). A window pops up. Name the project Logo and set the width to 250 pixels and the height to 120 pixels as shown below.

newfile

Now the first thing we are going to do is to fill the background for the logo. As the background I am going to use the darkest color (#1e2528). So first select this color. You do this by double clicking on the foreground color in the color section, which is this:

changeforeground

A new window will pop up. Set the hex value to 1e2528 as shown here:

setforeground

Now to fill in the background all you need to do is press Alt+Backspace together. The following is the result:

background

The next thing is to create the diamond. First go to layer menu and choose New and then Layer. Name the layer diamond. Then press U and the tool to draw shapes is chosen. From the top choose the rectangle tool. Now change the foreground color to gold (#cfb52b). Always remember to save and till now save in PSD format. Now draw a rectangle in the upper left corner of the image. Do not draw it too big, something like this:

diamond1

Now create another layer (Layer -> New -> Layer) and name it diamondfill. Then select the Eyedropper tool or press I as a shortcut and click on the dark colour. The foreground will automatically change to that colour. Then select the rectangle tool again or press U. We are going to draw a rectangle inside the gold rectangle like this one below. If you are not happy with the position choose the move tool (or press V) and move it until you are satisfied.

diamond2

The next thing we need to do is to merge the diamond layer and the diamondfill layer into one layer. We do this by selecting the diamondfill layer (click on it in the layers view). Then go to Layer and choose Merge Down (or press Ctrl+E). You should now have two layers Background and diamond. Now we need to rotate the diamond to become like an actual diamond. To do this we choose the diamond layer and then press Ctrl+T. A number of small boxes have formed at the edges of our rectangle. Go on the one at the top right corner. The arrow will change and now you can rotate the rectangle to form a diamond like this one below. You can even resize it if you think it is big/small.

diamond3

The next step is to write the name of the company. To do this we press the Horizontal Type Tool (or press T). Now choose Monotype Corsiva for the font family, 78pt for the size and make sure that the color is the gold color (#cfb52b). The Horizontal Type Tool toolbar should have the settings as this one.

texttoolbar

We should now have the following in our Photoshop file.

logo1

Are you noticing something? Well the affect of the diamond is not the desired one. So what we are going to do is add some glow to the diamond. To do this select the diamond layer. Double click on the diamond layer and a window will pop up. Then choose Inner glow and outer glow options as shown here:

layerstyle

The effect produced is definitely better. However there is something else that we can do to make it even better. Select the text layer (Marfel). Double – click on it and another window will pop up as before. This time choose drop shadow and then press OK. You should now have something like this:

logo2

This is way much better. Now what’s next? Well we have the name of the company. However this does not say what it does exactly. So our next step is to show that on this website the company will sell watches. So select the Horizontal Type Tool (or press T). Click somewhere so that the cursor appears. Change the colour of the text to light gray (#6a7378). Change the font size to 21pt and the font to Neuva Std. Set the style to Bold Condensed. Write the word ‘watches’. Then select the Move Tool (V) and place the word watches under Marfel near the ‘f’ letter as shown below.

logo3

Mmm nice! However the word watches seems very dull. So let’s double click on the watches layer. Now we need to choose Inner Shadow. Now click on outer glow and change the opacity in the outer glow settings to 100% as shown below.

layerstyle2

And you shall achieve the following result. Well the final product!!!

logo

Now to save it as an image, save the PSD file. Then go to Layer and then choose Flatten Image. Then go to File, choose Save as and save it as a PNG. Voila you have an image.

So the logo is ready. What’s next? Keep tuned the web layout is coming next and believe that’s more challenging and interesting. CU soon!! One last thing! For those of you who are interested here are a couple of books that will surely interest you:

Categories: Photoshop

Building a website the Big Brother way

December 30, 2008 scerrimark Leave a comment

Lately one of my friends wanted me to build a website for him. He has a business selling watches and he wants to take it online. Of couse I said yes. So you tell why should I care? Well I decided to go through the whole process with you. By whole process I mean from the design stage till its release!! So what does this include? Here it comes:

  • Gathering the requirements.
  • Designing the layout of the website.
  • Developing the website.
  • Setting up the website on a domain with a hosting company.
  • Releasing it with a bang.

OK the requirements are ready. Basically he needs an online shop where he can sell watches. Orders will be received by email at his office and then his staff will prepare the watches for delivery by the salesmen.

So what’s next? The next thing we need to do is to design the website layout. In layman terms this means drawing the layout on an image so that the client can see how the website will look. After that we’ll show it to the client and pray that he’ll like it, if not we’ll do the necessary changes.

How will we proceed? Well in the next post I am going to do a tutorial on how to create a website layout with Photoshop, and guess what? The website layout will be the same layout I will show to the client! So until then download Adobe Photoshop CS4 from here (it’s a 30 day trial – if you like it then buy it :) ), try to experiment a bit with it and then come back for the tutorial. Until then bye bye.

Categories: Website Development

C# .NET Tutorial 4: Converting between Types

December 30, 2008 scerrimark Leave a comment

Hello there! How are you? I hope you are all well. In this tutorial I will explain how we can convert between different types. It is important that you read tutorial 3 before attempting to read this tutorial. So let’s start.

C# unlike Visual Basic prohibits implicit conversion that lose precision. This means that in C# one cannot convert a double to an int. Implicit conversion is allowed only if the destination type can accomodate all possible values of the source type. This is called widening conversion:

double d = 1.0000001;
int i = 1;
d = i; //conversion allowed

If the range of the source type exceeds that of the destination type a narrowing conversion will take place or an explicit conversion. To perform explicit conversion in C# you need to use one of the following:

  • System.Convert – this can be used on types that implement the System.IConvertible interface.
  • (type) cast operator – used on types that define conversion operators.
  • type.ToString / type.Parse – between strings and base types; throws exception if conversion is not possible.
  • type.Parse / type.ParseExact – from string to a base type. Returns false if conversion is not possible.

Narrowing conversions fail if the source value exceeds the destination type range or if a conversion between the types is not defined.

Boxing and Unboxing

Boxing converts a value type to a reference type. Unboxing as you may have guessed correctly is converting a reference type to a value type. This example demonstrates how boxing work. We will convert an int (value type) to an Object (reference type):

int i = 29;
object o = (object) i;

Here is an example of unboxing:

object o = 123;
int i = (int) o;

Boxing and unboxing incur overhead so you should avoid them as much as possible. Boxing also occurs when you call virtual methods that a structure inherits from System.Object such as ToString. To avoid boxing:

  • Implement type-specific versions (overloads) for procedures that accept various value types.
  • Use generics whenever possible
  • Override the ToString, Equals, and GetHash virtual members when using structures.

Implementing Conversion in Custom Types

To define conversion on custom types you can do one of the following:

  • Define conversion operators to simplify narrowing and widening conversions between numeric types.
  • Override ToString and Parse to provide conversion between string and type.
  • Implement the System.IConvertible interface to allow conversions through System.Convert. Use this technique to enable culture-specific conversions.

Please not that conversion operators are new as from .NET 2.0.

In this example we will see how to define conversion operators:

struct TypeA
{
    public int value;

    //Allows implicit conversion from an integer
    public static implicit operator TypeA(int arg)
    {
        TypeA temp = new TypeA();
        temp.value = arg;
        return temp;
    }

    //Allows explicit conversion to an integer
    public static explicit operator int(TypeA arg)
    {
        return arg.value;
    }

    //Provides string conversion to avoid boxing
    public override string ToString()
    {
        return this.value.ToString();
    }
}

Now one can assign integers to the type directly as show here:

TypeA a;
int i;
//Widening conversion
a = 42;
//Narrowing conversion (must be explicit)
i = (int) a;
Console.WriteLine("a = {0} and i = {1}", a.ToString(), i.ToString());

To implement the System.IConvertible interface, add the IConvertible interface to the type definition. Then use Visual Studio to generate the 17 methods required by this interface. Automatically Visual Studio will include a throw exception for all the methods. You can leave them as they are and only change those methods you wish to implement. After you implement IConvertible, the custom type can be converted using the System.Convert as shown here:

TypeA a;
bool b;
a = 42;
//Convert using ToBoolean
b = Convert.ToBoolean(a);

Ok that’s it for today hope it was of interest to you. As always do leave your comments. In the next 4 tutorials we will be seeing input and output in C#. Until then enjoy!!!!

Categories: C# .NET

C# .NET Tutorial 3: Classes

December 29, 2008 scerrimark 1 comment

Hey welcome back to the third tutorial to this series on C#. To be able to follow this tutorial I am assuming that you have a basic grasp of the C# syntax and most importantly that you have good knowledge of the object oriented approach. I also recommend that you go through my first and second tutorial. In this tutorial I am going to discuss how classes are constructed.

Inheritance

In the .NET framework each class has a method, ToString, which performs the same task for each class. Other classes support the same operators, such as comparing two instances of a class for equality. This consistency is achieved through inheritance and interfacing. Let’s start with inheritance. Through inheritance you can create classes from existing ones and inherit their functionality plus adding your (new) functionality. Let’s get dirty straight away. In this example I will create a custom exception class that inherits from System.ApplicationException:

class CustomException : System.ApplicationException // : means that it will inherit from another class
{
    public override string Message
    {
        get {return "A custom error occurred in the application";}
    }
}

Because this new custom exception inherits from the base class you can throw and catch this exception as shown here:

try
{
    throw new CustomException();
}
catch (CustomException ce)
{
    Console.WriteLine(ce.Source + " " + ce.Message);
    //note that the Source was inherited from the base class while the Message was overridden in the new
    //custom exception we created
}

Another benefit of inheritance is that you can use classes that inherit from the same base class interchangeably. For example the System.Drawing.Brush is the base class for five other classes, which are HatchBrush, LinearGradientBrush, PathGradientBrush, SolidBrush, and TextureBrush. The Graphics.DrawRectangle method requires an instance of a Brush as one of the parameters. Any one instance of the five brushes mentioned can be used as a parameter.

Interface

An interface provides sort of an agreement or contract that defines a set of members that all classes that implement that interface must provide. For example the IComparable interface defines a CompareTo method, which enables two instances of the class to be compared for equality. Every class that implements the IComparable interface needs to have the CompareTo method. For a class to implement a particular interface you use the following:

class ExampleClass : IExampleInterface
{
}

Note that Visual Studio (or Visual C# Express Edition) can generate the methods that you need to implement from the Interface. This is done by right clicking the Interface declaration, then click on Implement Interface, and then on Implement Interface again.

The most commonly used interfaces in .NET are the following:

  • IComparable – implemented by types whose values can be ordered such as int and string.
  • IDisposable – contains methods that are used to dispose of the objects.
  • IConvertible – enables a class to be converted to a base type such as boolean, double, string, etc.
  • ICloneable – supports copying of objects.
  • IEquatable – allows you to compare two instances of a class for equality.
  • IFormattable – enables you to convert an object to a formatted string.

Let us create an interface now:

interface IShape
{
    double Area(); //computes the area of a shape
    double Volume(); //computes the volume of a shape
    string Name { get; }
}

This is an interface for shape classes. Each shape must have a name and it must have methods to compute the area and volume.

In Visual Studio you can create a class and then extract an interface from it. Right-click the class, click Refactor, and then click Extract Interface.

Classes can also implement multiple interfaces.

Partial Classes

Partial classes are new in .NET 2.0. They allow you to split a class into multiple source files. The Windows form is an exmple of a partial class in .NET. The code generated by the form designer (while designing a windows form) is “hidden” in a partial class named  form.Designer.cs (where form is the name of your windows form).

Generics

Generics were also introduced in .NET 2.0 and are part of the .NET type system that allows you to define a type while leaving some of the details unspecified. Instead of specifying the types of parameters or member classes, you can allow the code that uses your type to specify it. This allows your code to tailor your type to its own specific needs. The .NET framework contains generic classes in the System.Collections.Generic such as the Dictionary, Queue, SortedDictionary, and SortedList. These classes work similar to the non-generic counterparts in System.Collections but they have better performance and type safety.

In the previous .NET versions developers used the Object to cast other classes. Generics offer advantages over the Object class:

  • Improved performance – casting requires boxing and unboxing, which we will cover in future tutorials, that require the processor’s attention therefore it slows performance. Generics do not require these.
  • Reduced run-time errors – the compile will not detect type errors when casting to and from an Object. For example if a string is cast to an Object and then that Object is cast to an integer an error occurs at run-time. Generics allow the compiler to catch this type of error.

To better understand generics let us build an example. We will create two classes, one that uses the Object and the other that uses generics:

class Obj //using Object
{
    public Object a;
    public Object b;

    public Obj(Object a, Object b)
    {
        this.a = a;
        this.b = b;
    }
}

class Gen<A,B> //using generics
{
    public A a;
    public B b;

    public Gen(A a, B b)
    {
        this.a = a;
        this.b = b;
    }
}

Note that generic code is valid only if it will compile for every possible constructed instance of the generic. This means that you are limited to the capabilities of the base Object class. Therefore you can call the ToString method (because this is implemented by all types) but you cannot use the + and > operators.

To understand further how generics are used I will present an application that uses the Obj and Gen classes we created above:

//add 2 strings using the Obj class
Obj o = new Obj("Hello","Blog");
Console.WriteLine((string)o.a + (string)o.b);

//add 2 strings using the Gen class
Gen<string,string> g = new Gen<string,string&gt("Hello", "Blog");
Console.WriteLine(g.a + g.b);

//adding an int and a double with Obj class
Obj o2 = new Obj(1, 1.2905);
Console.WriteLine((int)o2.a + (double)02.b); 

//adding an int and a double with Gen class
Gen<int,double> g2 = new Gen<int,double>(1, 1.2905);
Console.WriteLine(g2.a + g2.b);

As such the two classes do the same thing. However when we use a generic class we do not need to cast and therefore it is much more efficient. With the generic class we also ensure that any type errors occur at run-time.

By now you may be saying: Generics are limited if we can write code based on the capabilities of the Object base class. Well that is where constraints come into play. Constraints place requirements on the types that the consuming code can substitute for the generic.

Generics support four types of constraints:

  • Interface – allow only types that implement a certain interface.
  • Base class – allow only types that inherit from a particular base class.
  • Constructor – requires types that use your generic to implement a parameterless constructor.
  • Reference or value type – require types to be either a reference or value type.

To apply generics we use the where clause. In the following example we will create a generic that will allow types that implement the IComparable interface:

class CompareGeneric<T> where T : IComparable
{
    public T t1;
    public T t2;

    public CompareGeneric (T t1, T t2)
    {
        this.t1 = t1;
        this.t2 = t2;
    }

    public T Max()
    {
        if (t2.CompareTo(t1) < 0)
        {
            return t1;
        }
        else
        {
            return t2;
        }
    }
}

This code will only work because of the statement where T : IComparable. If we remove it the compiler will return an error indicating that generic type T does not contain a definition for CompareTo.

Events

Most applications are not linear. They respond to events such as a user clicking a button or when an incoming message is received on a server, etc.

An event is a message sent by an object to indicate the occurrence of an action. The action can be caused by user interaction, or it could be triggered by some other program logic. The object that raises the event is called the event sender. The object that handles the event is the event receiver.

The event sender class does not know which object or method will receive the event. We need an intermediary to act as a pointer between the sender and the receiver. The .NET framework defines a special type that provides the functionality of a function pointer. This is called a delegate.

A delegate is a class that can hold a reference to a method. A delegate has a signature and can hold references to methods with the same signature. It is equivalent to a type-safe function pointer or callback. The following shows a delegate function declaration:

public delegate void ClickEventHandler(object sender, EventArgs e);

The standard signature for an event handler delegate defines a method that does not return a value (void), whose first parameter is of type Object (referring to the instance that raised the event), and the second parameter is derived from the EventArgs and holds the event data.

To associate the event with a method to handle the event, add an instance of the delegate to the event. The event handler is called whenever the event occurs.

Here is an example to make things clearer. We will see how to respond to an event:

  • Create a method to respond to the event. It must match the Delegate signature:
    private void button_click(object sender, EventArgs e)
    {
        //put code here
    }
  • Add the event handler as an instance of the delegate:
    this.button1.click += new System.EventHandler(this.button_click); //System.EventHandler is the delegate
  • When the event occurs that method will be called.

To raise an event you must do the following steps:

  • Create a delegate:
    public delegate void MyEventHandler(object sender, EventArgs e);
  • Create an event member:
    public event MyEventHandler MyEvent;
  • Invoke the delegate within a method when you need to raise the event:
    MyEventHandler handler = MyEvent;
    EventArgs e = new EventArgs();
    
    if (handler != null)
    {
        //Invokes the delegate
        handler(this, e);
    }
    //C# checks whether handler is null

Attributes

Attributes describe a type, method, or property in a way that can be programmatically queried using a technique called Reflection.  Some common uses of attributes are to:

  • specify which security privileges a class requires
  • specify security privileges to refuse to reduce security risk
  • declare the assembly by providing a title, description, and copyright notice
  • declare capabilities, such as supporting serialization.

Attribute types derive from the System.Attribute base class and are specified using [ and ]. The following shows how to add  assembly attributes:

[assembly: AssemblyTitle("blog")]
[assembly: AssemblyDescription("This is a blog")]
[assembly: AssemblyCompany("scerrimark.com")]
[assembly: AssemblyProduct("C# tutorial")]
[assembly: AssemblyTrademark("")]

Visual Studio automatically creates some standard attributes for your assembly when you create a project, including title, company, description, guide, and version.

Attributes can also declare requirements and capabilities. For example to enable a class to be serialized you must add the Serializable attribute:

[Serializable]
class Account
{
}

The following code uses attributes to declare that it needs to read the C:\boot.ini file. Because of this attribute, the run-time will throw an exception if it lacks the specified privilege:

using System;
using System.Security.Permissions;

[assembly: FileIOPermissionAttribute(SecurityAction.RequestMinimum, Read=@"C:\boot.ini"]
namespace DeclarativeExample
{
    class ExampleClass
    {
    }
}

Type Forwarding

Suppose you have created an assembly named MyLibrary which contains a class named MyClass. Let’s say, some of your applications refer to the MyLibrary assembly and utilizes MyClass. In a later phase, you decide to move MyClass from MyLibrary to a newly created assembly called MyAdvancedLibrary. If you ship a new version of MyLibrary (which now doesn’t have MyClass), along with MyAdvancedLibrary, then your existing applications looking for MyClass in MyLibrary will not find the MyClass and end up with errors. The solution is type forwarding.

Type forwarding is an attribute that allows you to move a type from one assembly into another assembly, and to do so in such a way that it is not necessary to recompile clients that consume the first assembly. After a component ships and is being used by client applications, you can use type forwarding to move a type from the component into another assembly and ship the updated component, and the client applications will still work without being recompiled. To move a type from one class library to another:

  • Add a TypeForwardedTo attribute to the source class library assembly.
  • Cut the type definition from the source class library.
  • Paste the definition into the destination class library.
  • Rebuild both libraries.

The following code shows the attribute declaration used to move MyClass to the MyAdvancedLibrary class library.

using System.Runtime.CompileServices;
[assembly: TypeForwardedTo(typeof(MyAdvancedLibrary.MyClass))]

Well for today that’s enough!! So how are you feeling? Are you finding these tutorials good? Well leave a comment below. I ‘ll see you for the next tutorial: Converting between types.

Categories: C# .NET

C# .NET Tutorial 2: Reference Types

December 27, 2008 scerrimark 1 comment

Hello there welcome to the second tutorial on C#. If you haven’t read the first tutorial then I suggest that you read it. So let’s start straight away.

Reference types provide a lot of flexibility and offer better performance when they are passed to methods. But what is really a reference type? Unlike value-types reference types store an address of the data (aka pointer) on the stack. The actual data will be found at that address on heap. The heap is managed at runtime and items on the heap that are not needed anymore are removed by the garbage collector.

To better understand let us compare reference-type variables with value-type variables.

The first difference is this. Because reference-type variables only contain the address of memory where the data is stored if you assign this variable to another variable you will have another variable pointing to the same address in memory. Therefore these two variables are pointing to the same data on heap. This implies that if you change the value of one variable the value of the second variable will be changed automatically because they are both pointing to the same thing! Let us see through an example:

NumberClass c1 = new NumberClass(4);
Console.WriteLine(c1.Value); //This will display 4.

NumberClass c2 = c1;
Console.WriteLine(c2.Value); //This will display 4.

c1.Value += 1;
Console.WriteLine(c1.Value); //This will display 5.

Console.WriteLine(c2.Value); //This will display 5 because both c1 and c2 point to the same thing.

Built-In Reference Types

In .NET everything that is not derived from System.ValueType is a reference type. So as you can imagine there are a lot. Here I list the six most common (and the most you will use):

  • System.Object: This is the most general. You can convert any type to System.Object. Because of this any type in .NET will have the ToString, GetType, and Equals members inherited from this type.
  • System.String: used to store text.
  • System.Array: this keeps an array of data and is the base class of all arrays.
  • System.Text.StringBuilder: used to store dynamic text data.
  • System.Exception: it handles system and application-defined exceptions. Any exception (even user defined) inherits from this.
  • System.IO.Stream: This is an abstract base class and it defines a buffer for file, network I/O, device I/O, etc.

In the next sections we look at each of these built-in references.

Strings and String Builders

The System.String provides a number of members that can be used to manipulate text. For example to search and replace in a string you use the following:

string s = "This blog contains C sharp tutorials";
s = s.replace("sharp", "#");

So what happens when the contents of a string change? Strings in .NET are immutable. When a string changes a new string is created and the old one is discarded. This is invisible to the programmer however it is important that one knows because creating extra strings means the garbage collector needs to spend more time collected unreferenced (not used) strings. Consider this example:

string s = "This";
s += " is";
s += " a";
s += " blog";

This example has caused 3 temporary strings, which the garbage collector has to remove during runtime. Avoiding these temporary strings will improve performance. To avoid temporary strings:

  • Use the String class’ Concat, Join, and Format methods, and
  • Use the StringBuilder to create dynamic (mutable) strings.

With the StringBuilder you can specify the size of the string. The default created by the constructor is 16 bytes long. You can specify an initial size and the maximum size. For example:

System.Text.StringBuilder s = new System.Text.StringBuilder(30) // 30 bytes long
s.Append("This ");
s.Append("is a ");
s.Append("blog");
string message = s.ToString(); //convert to a string

The String class overrides operators from System.Object. These are:

  • Addition (+) – concatenates two strings.
  • Equality (==) – returns true if content of two strings are the same else it returns false.
  • Inequality (!=) – the opposite of equality.
  • Assignment (=) – copies the contents of one string to another (acts like value types even though they are reference types).

How to create and sort Arrays

As with the string type the System.Array provides members that can be used to work on the data present in the array. In C# arrays are declared using square brackets []. For example in the code below we will create an array and sort it:

//create a int array
int[] arr = {22,1,85,19,29,0,5};
//sort the array by calling a static method
Array.sort(arr);

Using Streams

Streams can be used to read and write to disk and communicating over a network. For whatever reason you use a stream all streams are derived from System.IO.Stream. Network streams can be found in System.Network.Sockets, and encrypted streams can be found in System.Security.Cryptography. The following are the most common streams that you will use:

  • FileStream – used to write or read, to or from files.
  • MemoryStream – used to write or read, to or from memory.
  • StreamReader – reads from a stream.
  • StreamWriter – writes to a stream.

The StreamReader and the StreamWriter accept the path of a text file as a parameter in the constructor. The following code, which needs the System.IO namespace, shows how to read and write to a text file:

//write to a text file
StreamWriter sw = new StreamWriter("blog.txt");
sw.WriteLine("C# tutorial!");
sw.Close();

//read from a text file
StreamReader sr = new StreamReader("blog.txt");
//display on screen
Console.WriteLine(sr.ReadToEnd());
sr.Close();

Later on in this series of tutorials I will dedicate a number of tutorials solely for I/O.

Exceptions

Exceptions are events that occur unexpectedly. For example a typical exception is when an application is trying to perform a mathematical division and the divisor is 0 like 4/0. Another typical example that will cause an exception is when an applilcation is trying to read from a file that does not exist on disk.

A good programmer will anticipate such exceptions and thus handle them in his/her code so that the application does not stop abruptly. In the following code we handle an exception that may occur while reading from a file (this code requires System.IO namespace):

try
{
    StreamReader sr = new StreamReader("test.txt");
    Console.WriteLine(sr.ReadToEnd());
}
catch (Exception ex)
{
    Console.WriteLine("Error reading file");
}

If any type of error occurs while reading the file the code goes in the catch block. If no error occurs the code will not go in the catch block. In this particular example any error that may occur will be caught. This is because we used the Exception class which is the base of all possible exception. Other more specific exceptions exist all deriving from System.SystemException. You can create your own more specific exceptions by deriving them from System.ApplicationException. One can also have multiple exception handlers to do different things according to the excption that occured. Here is an example that displays different error messages if a file is not found, if the user does not have the sufficient privileges, and any other type of error:

try
{
    StreamReader sr = new StreamReader("test.txt");
    Console.WriteLine(sr.ReadToEnd());
}
catch (System.IO.FileNotFoundException ex)
{
    Console.WriteLine("File not found!");
}
catch (System.UnauthorizedAccessException ex)
{
    Console.WriteLine("You do not have sufficient privileges to open this file!");
}
catch (Exception ex)
{
    Console.WriteLine("An error occurred while reading from file!");
}

While handling exceptions one can also include a finally section with the try catch block. The finally block is always executed irrespective whether an exception has occurred or not. Therefore the finally block should be used to do some clean up after your code. For example in the previous examples we were opening a stream but never closing it. We should close the stream in the finally block. This means that whether data is read successfully from the stream or not we will close the stream at the end:

//Stream declaration was moved outside so that it is available to both the try and finally blocks
StreamReader sr;

try
{
    sr = new StreamReader("test.txt");
    Console.WriteLine(sr.ReadToEnd());
}
catch (Exception ex)
{
    Console.WriteLine("Error reading from file!");
}
finally
{
    sr.Close(); //stream is closed
}

Typically all code except for variable declarations should occur between try..catch blocks. Exception handling improves the user experience and will even help you while debugging your code. However always keep in mind that it incurs a slight performance penalty.

Hope you liked this second tutorial. Please leave comments if you have any queries or if you want to change something. Until then see you for the next tutorial: Creating Classes. Bye Bye!

Categories: C# .NET