Page 1 of 1

System.IO in C# Part II

#1 PsychoCoder   User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1663
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Posted 02 September 2007 - 07:02 PM

Welcome to the System.IO in C# Part II tutorial. In the System.IO Operations in C# Part I tutorial we looked at reading and writing with text files. We learned how to write to a text file, how to read a text file a line at a time, how to read a text file all at once, and how to check if a file exists before attempting to read from it, this is all done with the System.IO.File Class in the .Net 2.0 Framework.

In this tutorial we will look at some more intermediate tasks, such as converting a comma delimited file to an XML document, moving,copying and deleting file and how to access file properties using the System.IO.File and System.IO.Directory Classes. At the end of this tutorial I will be including both the DLL file I created for handling System.IO work, along with the source code.

This code is under GNU General Public License, meaning you can alter and modify it how you see fit I am also uploading both the DLL file and the source code, all I ask is that you keep my header in tact. I have no problems with anyone using this commercially, but if you do it would be nice if there was a mention of me somewhere, possibly just a link back to this tutorial.

The first thing we'll take a look at is converting a comma delimited file into an XML document. The most efficient way to accomplish this was to convert the file to a DataSet, then use the WriteXML Method of the DataSet. The function requires 3 parameters:
  • delimiter: Char value of the delimited to look for in the file
  • file: The file to convert
  • xmlFileName: Name of the XML file to create
Now lets take a look at the function

/// <summary>
/// Function to convert a delimited file to an XML document
/// </summary>
/// <param name="delimiter">Delimiter to check for in the file</param>
/// <param name="file">File to convert</param>
/// <param name="xmlFileName">Name of the resulting XML document</param>
public void ConvertDelimitedToXML(char delimiter, string file,string xmlFileName)
{
	//create the objects we need
	System.Data.DataSet xmlDataSet = new System.Data.DataSet();
	System.Data.DataTable xmlTable = new System.Data.DataTable();
	System.Data.DataRow xmlRows;
	//always use a try...catch block to catch any errors
	try
	{
		using (StreamReader reader = new StreamReader(file))
		{
			//set the DataSetName of the DataSet
			xmlDataSet.DataSetName = "YourName";
			//set the NameSpace of the DataSet
			xmlDataSet.Namespace = "YourNamespace";

			//make sure we're at the beginning of the file
			reader.BaseStream.Seek(0, SeekOrigin.Begin);
			//add the header columns
			foreach (string fields in reader.ReadLine().Split(delimiter))
			{
				//xmlDataSet.Tables(0).Columns.Add(fields);
				xmlTable.Columns.Add(fields);
			}
			//now loop through all the rows
			while (reader.Peek() != -1)
			{
				xmlRows = xmlTable.NewRow();
				//loop through all the items in the row
				//and add them to the DataTable row
				foreach (string fields in reader.ReadLine().Split(delimiter))
				{
					xmlTable.Rows.Add(fields);
				}
				//add the new rows to the table
				xmlTable.Rows.Add(xmlRows);
			}
			//add the table to the DataSet
			xmlDataSet.Tables.Add(xmlTable);
			//write out the XML
			xmlDataSet.WriteXml(xmlFileName);
		}	 
	}
	catch (Exception ex)
	{
		//deal with any errors
		Console.WriteLine(ex.Message);
	}				 
}



Thats it, provide a file, the delimiter to look for and the name you want the XML document to be named and this creates it for you, pretty simply. Now lets take a look at copying files to a new directory, here we will take a look at
  • Copying a single file to a new directory
  • Copying all files in a specified directory to a new directory
When copying a file, it takes the original file and copies all of its contents to the new file you specify. The CopySingleFile method required 2 parameters
  • origFile: Name of the original file we're copying
  • destFile: Name of the destination file
Both of these parameters allow for relative or absolute paths to both files. In this method I also have a line to delete the original file once the copy is complete, if you do not want to remove the original file simply comment that line out, its marked with a TODO:.

The first thing this method does is to check and see if the destination file already exists, if it does it deletes the file to prevent an exception from being raised. It then uses the File.Copy Method to copy the file to its new file/location.

NOTE: The File.Copy Method has a single overload allowing for the destination file to be overwritten. File.Copy(origFile,destFile,boolean) Setting boolean to True will allow the overwriting of the destination file.

First, copying a single file

/// <summary>
/// Method for copying a single file
/// </summary>
/// <param name="origFile">Path & file of the file to copy</param>
/// <param name="destFile">Path & name of the destination file</param>
public void CopySingleFile(string origFile, string destFile)
{
	//always use a try...catch to deal 
	//with any exceptions that may occur
	try
	{
		//check if the destination file exists,
		//if it does we need to delete it, .Copy
		//will raise an exception otherwise
		if(System.IO.File.Exists(destFile))
		{
			System.IO.File.Delete(destFile);
		}
		//now we can copy the file
		System.IO.File.Copy(origFile, destFile);
		//now delete the original file
		//TODO: Comment this line if you dont
		//want to delete the original file
		System.IO.File.Delete(origFile);
		Console.WriteLine("File copied successfully");
	}
	catch (Exception ex)
	{
		//handle any errors that occurred
		Console.Write(ex.Message);
	}
}



Copying all the files in a directory takes a bit more code to accomplish. This method requires 2 parameters as well
  • origDir: The directory the files are currently in
  • destDir: The directory to copy the files to
As with the previous example, these 2 parameters can be either relative or absolute paths. Next it retrieves all the information about the files in the original directory, then it calls System.IO.File.Copy using the OverWrite overload the copy the files and overwrite the destination file if it already exists. Once the files are copied it then deletes the files in the original directory.

NOTE: If you dont want to delete the original files then comment the line that deletes them, its marked with a TODO:.

Now for the method for copying all the files in a directory to their new home

/// <summary>
/// Method for copying all the files
/// in a specified directory
/// </summary>
/// <param name="origDir">Directpry the files are in</param>
/// <param name="destDir">Directory the files are being copied to</param>
public void CopyAllFilesInDirectory(string origDir, string destDir)
{
	//get all the info about the original directory
	DirectoryInfo dirInfo = new DirectoryInfo(origDir);
	//retrieve all the files in the original directory
	FileInfo[] files = dirInfo.GetFiles(origDir);
	//always use a try...catch to deal 
	//with any exceptions that may occur
	try
	{
		//loop through all the files and copy them
		foreach (string file in System.IO.Directory.GetFiles(origDir))
		{
			FileInfo origFile = new FileInfo(file);
			FileInfo destFile = new System.IO.FileInfo(file.Replace(origDir,destDir));
			//copy the file, ose the OverWrite overload to overwrite
			//destination file if it exists
			System.IO.File.Copy(origFile.FullName, destFile.FullName,true);
			//TODO: If you dont want to remove the original
			//files comment this line out
			System.IO.File.Delete(origFile.FullName);
		}
		Console.WriteLine("All files in " + origDir + " copied successfully!");
	}
			catch (Exception ex)
	{
		//handle any errors that may have occurred
		Console.WriteLine(ex.Message);
	}
}



Another intermediate task in the System.IO is deleting files, you can either delete a single file, or delete all the files in a directory. As you can imagine, the method for deleting a single file requires a single parameter
  • file: The file to be deleted. This can contain either the absolute or relative path to the file
In these examples we will be introduced to the Delete Method of the System.IO.File Class. When using Delete you pass it the path to the file you want to delete, then call
System.IO.File.Delete(file).

NOTE: if the files doesnt exist an exception will be raised, so always check first to be sure the file exists.

So lets see how to delete a single file

/// <summary>
/// Method for deleting a single file
/// </summary>
/// <param name="file">The file to delete</param>
public void DeleteSingleFile(string file)
{
	//always use a try...catch to deal 
	//with any exceptions that may occur
	try
	{
		//make sure the file exists
		//if it doesnt raise an error
		if(!System.IO.File.Exists(file))
		{
			throw new FileNotFoundException(file + " cannot be found!");
		}
		else
		{
			//delete the file
			System.IO.File.Delete(file);
			Console.WriteLine(file + " deleted successfully!");
		}
	}
	catch (Exception ex)
	{
		//handle errors that may have occurred
		Console.WriteLine(ex.Message);
	}
}



This is pretty straight forward, you pass it a file, it checks if the file exists, if it doesnt it throws an Exception otherwise it deletes the file. Deleting all the files in a provided directory requires a bit more work (not that its hard, just more logic).

When deleting all the files in a provided directory we must first check and make sure the directory actually exists, otherwise an Exception is thrown. We then use Directory.GetFiles() to retrieve all the filenames in the directory and place them into a string array. Once we have this string array, we loop through it deleting the files one at a time.

NOTE: Use a try...catch block to trap any Exceptions that are raised during the delete process.

Now for the code

/// <summary>
/// Method for deleting all the files
/// in a specified directory
/// </summary>
/// <param name="dir">Directory to delete from</param>
public void DeleteAllFilesInDirectory(string dir)
{
	//always use a try...catch to deal 
	//with any exceptions that may occur
	try
	{
		//first make sure the directory exists
		//if it doesnt and we try to delete the 
		//files an exception is thrown
		if (!System.IO.Directory.Exists(dir))
		{
			//throw the exception to be
			//dealt with later
			throw new DirectoryNotFoundException(dir + " cannot be found! Please retry your request");
		}
		else
		{
			//retrieve all the files and put them into a string array
			string[] files = Directory.GetFiles(dir);
			//now loop through all the files and delete them
			foreach(string file in files)
			{
				System.IO.File.Delete(file);
			}
			//let the user know it was successful
			Console.WriteLine("All files deleted successfully!");
		}
	}
	catch (Exception ex)
	{
		//handle any errors that occurred
		Console.WriteLine(ex.Message);
	}
}



There are a few exceptions that are thrown while working with files and directories in the System.IO Namespace:Granted, there are many more exceptions that can occur when working with the System.IO Namespace, these are just to most common.

NOTE: To avoid an exception because the file you're working with is open and in use you can use this method to check if the file is currently open

/// <summary>
/// Method to determine if a file is open
/// </summary>
/// <param name="file">File to check</param>
/// <returns>Boolean value</returns>
public static Boolean ReturnIsFileOpen(string file)
{
	Boolean isOpen = false;
	//always use a try...catch to deal 
	//with any exceptions that may occur
	try
	{
		//check if the file exists, if it 
		//doesnt exist raise an error
		if (!System.IO.File.Exists(file))
		{
			throw new FileNotFoundException(file + " could not be found!");
		}
		else
		{
			FileStream stream = System.IO.File.OpenRead(file);
			stream.Close();
		}
	}
	catch
	{
	   isOpen=true;
	}
	return isOpen;
}



Here we use the OpenRead Method to open the file for reading, if the file is already open an exception is raised and in our catch statement we set our boolean isOpen to True.

There are many more tasks one can accomplish with the System.IO Namespace other than moving, copying and deleting files. You can set and retrieve FileInfo Properties (Size, ReadOnly Status, LastAccessTime etc), so lets look at a couple.

Lets say that after you copy a file to its new location you want to make it a read only file, you could use this method

/// <summary>
/// Method to set the ReadOnly property of a file
/// </summary>
/// <param name="file">File to set property of</param>
/// <param name="readOnly">Value of ReadOnly</param>
public static void SetReadOnly(string file, bool readOnly)
{
	//always use a try...catch to deal 
	//with any exceptions that may occur
	try
	{
		//check if the file exists, if it 
		//doesnt exist raise an error
		if (!System.IO.File.Exists(file))
		{
			throw new FileNotFoundException(file + " could not be found!");
		}
		else
		{
			//set the readonly status to the parameter
			//passed to the method
			FileInfo fInfo = new FileInfo(file);
			fInfo.IsReadOnly = readOnly;
		}

		
	}
	catch (Exception ex)
	{
		//handle any errors that occurred
		Console.WriteLine(ex.Message);
	}
}



Here we check to ensure the file exists, then we get the FileInfo of the file name provided and set its IsReadOnly Property to the boolean value we pass it. In the class file provided there are more examples of setting and retrieving file information using the FileInfo Properties of the System.IO Namespace.

Well that is the end of Part II of this tutorial, thanks for reading :)

Attached File  SystemIO.zip (62.05K)
Number of downloads: 1696

This post has been edited by PsychoCoder: 02 September 2007 - 11:37 PM


Is This A Good Question/Topic? 0
  • +

Replies To: System.IO in C# Part II

#2 [email protected]   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 07-March 10

Posted 07 March 2010 - 05:25 AM

Hi PsychoCoder

In was just wondering:

Shouldnt this line of code:
FileInfo[] files = dirInfo.GetFiles(origDir);

be changed to:
FileInfo[] files = dirInfo.GetFiles();

I dont think any of the get files method overloads takes a file path argument...

and shouldnt this line of code:
foreach (string file in System.IO.Directory.GetFiles(origDir))

be changed to:
foeach(string file in files)

seeing as you had already declared an array of files named files containing all the files in your dirInfo object.

Thanks for all these great tutorials though, have helped me a lot...
do you know how to go about changing your username? cant seem to find a way on this site to do that...

that code came from your CopyFilesInDirectory Method

This post has been edited by [email protected]: 07 March 2010 - 05:34 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1