Practical Techniques for File Operations and Data Serialization in C#
File-based storage is optimal for managing substantial volumes of data with simple relationships, such as application logs, offering accessibility across various storage media. The .NET framework provides stream-based APIs for file interaction.
Common File and Directory Operations
Obtain the current application directory.
string appDirectory = Directory.GetCurrentDirectory();
Write data to a new file.
using (FileStream fileOutput = new FileStream(appDirectory + "\\data.txt", FileMode.Create))
using (StreamWriter textWriter = new StreamWriter(fileOutput))
{
textWriter.Write(dataTextBox.Text.Trim());
}
Read the entire contents of a file.
using (FileStream fileInput = new FileStream(appDirectory + "\\data.txt", FileMode.Open))
using (StreamReader textReader = new StreamReader(fileInput))
{
dataTextBox.Text = textReader.ReadToEnd();
}
Append a line to an existing file.
using (FileStream fileOutput = new FileStream(appDirectory + "\\data.txt", FileMode.Append))
using (StreamWriter textWriter = new StreamWriter(fileOutput))
{
textWriter.WriteLine(DateTime.Now.ToString() + " Operation successful.");
}
Delete a specified file.
File.Delete(sourcePath.Text.Trim());
Copy a file, deleting the target if it existts.
string destFile = destinationPath.Text.Trim();
if (File.Exists(destFile))
File.Delete(destFile);
File.Copy(sourcePath.Text.Trim(), destFile);
Move a file, after checking for its existence.
string destPath = destinationPath.Text.Trim();
string srcPath = sourcePath.Text.Trim();
if (File.Exists(destPath))
File.Delete(destPath);
if (File.Exists(srcPath))
File.Move(srcPath, destPath);
else
Console.WriteLine("Source file not found.");
List all files and subdirectories in a given path.
string[] fileList = Directory.GetFiles(appDirectory);
contentTextBox.Clear();
foreach (string file in fileList)
contentTextBox.Text += file + Environment.NewLine;
string[] directoryList = Directory.GetDirectories(appDirectory);
contentTextBox.Clear();
foreach (string dir in directoryList)
contentTextBox.Text += dir + Environment.NewLine;
Create a nested directory.
Directory.CreateDirectory(appDirectory + "\\MyFiles\\SubFolder");
Delete a directory and all its contents.
DirectoryInfo targetDir = new DirectoryInfo(appDirectory + "\\MyFiles");
targetDir.Delete(true);
Recursively copy a directory structure.
public static void CopyDirectoryRecursive(string sourceDir, string targetDir)
{
if (targetDir[targetDir.Length - 1] != Path.DirectorySeparatorChar)
targetDir += Path.DirectorySeparatorChar;
if (!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
string[] entries = Directory.GetFileSystemEntries(sourceDir);
foreach (string entry in entries)
{
if (Directory.Exists(entry))
CopyDirectoryRecursive(entry, targetDir + Path.GetFileName(entry));
else
File.Copy(entry, targetDir + Path.GetFileName(entry), true);
}
}
Check if a directory exists.
if (!Directory.Exists(logPath))
{
// Directory does not exist
}
Create, move, and delete directories.
Directory.CreateDirectory(logPath);
Directory.Move(logPath, newLogPath);
Directory.Delete(newLogPath);
Create a text file using various methods.
string dataString = "Sample data";
using (FileStream fs = File.Create(fileName))
{
byte[] dataBytes = Encoding.Default.GetBytes(dataString);
fs.Write(dataBytes, 0, dataBytes.Length);
}
using (FileStream fs = File.Create(fileName))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("1234567890");
}
using (StreamWriter sw = File.AppendText(fileName))
{
sw.WriteLine("Appended line.");
}
Read a file using different approacehs.
// Read all lines into memory
foreach (string line in File.ReadAllLines(fileName))
Console.WriteLine(line);
string allText = File.ReadAllText(fileName);
byte[] fileBytes = File.ReadAllBytes(fileName);
string textFromBytes = Encoding.UTF8.GetString(fileBytes);
// Read in chunks
using (FileStream stream = File.OpenRead(fileName))
{
int bufferSize = 5;
int bytesRead;
do
{
byte[] buffer = new byte[bufferSize];
bytesRead = stream.Read(buffer, 0, bufferSize);
for (int i = 0; i < bytesRead; i++)
Console.WriteLine(buffer[i].ToString());
} while (bytesRead == bufferSize);
}
Copy, move, and delete operations using File static methods.
File.Copy(sourceFile, copyFile);
File.Move(sourceFile, moveFile);
File.Delete(moveFile);
Retrieve drive information.
DriveInfo[] allDrives = DriveInfo.GetDrives();
foreach (DriveInfo d in allDrives)
{
if (d.IsReady)
Console.WriteLine($"Drive: {d.Name} Type: {d.DriveType} Total Size: {d.TotalSize} Free: {d.TotalFreeSpace}");
}
Useful Path class methods.
Console.WriteLine(Path.GetDirectoryName(@"d:\abc")); // Returns d:\
Console.WriteLine(Path.GetRandomFileName());
Console.WriteLine(Path.GetFileNameWithoutExtension(@"d:\abc.txt")); // Returns abc
Console.WriteLine(Path.Combine(logPath, "log.txt")); // Merges paths
Object Serialization
Storing complex objects as plain text is inefficient and insecure. Serialization converts an object graph into a stream, which can be deserialized back into objects.
Define a serializable class.
[Serializable]
public class Person
{
public string FullName { get; set; }
public string Gender { get; set; }
public int Age { get; set; }
public DateTime DateOfBirth { get; set; }
}
Serialize an object to a file.
using System.Runtime.Serialization.Formatters.Binary;
Person person = new Person() { FullName = "John Doe", Age = 30, Gender = "Male", DateOfBirth = new DateTime(1993, 5, 15) };
using (FileStream fs = new FileStream(@"C:\person.dat", FileMode.Create))
{
BinaryFormatter serializer = new BinaryFormatter();
serializer.Serialize(fs, person);
}
Deserialize an object from a file.
using (FileStream fs = new FileStream(@"C:\person.dat", FileMode.Open))
{
BinaryFormatter serializer = new BinaryFormatter();
Person restoredPerson = (Person)serializer.Deserialize(fs);
// Use restoredPerson properties
}
XML Data Handling
XML is a markup language for structured data storage, defined by a single root element, nested tags, and quoted attributes.
Parse an XML document and popluate a list.
using System.Xml;
XmlDocument doc = new XmlDocument();
doc.Load(@"Students.xml");
XmlNode root = doc.DocumentElement;
List<Student> studentList = new List<Student>();
foreach (XmlNode studentNode in root.ChildNodes)
{
if (studentNode.Name == "Student")
{
Student s = new Student();
foreach (XmlNode propertyNode in studentNode)
{
switch (propertyNode.Name)
{
case "Name": s.Name = propertyNode.InnerText; break;
case "Age": s.Age = Convert.ToInt16(propertyNode.InnerText); break;
case "Gender": s.Gender = propertyNode.InnerText; break;
case "Class": s.Class = propertyNode.InnerText; break;
}
}
studentList.Add(s);
}
}
dataGridView.DataSource = studentList;
JSON Serialization
JSON provides a lightweight format for data interchange.
Helper class for JSON operations.
using Newtonsoft.Json;
using System.Web.Script.Serialization;
public static class JsonUtility
{
// Using JavaScriptSerializer
public static string SerializeObject<T>(T data)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Serialize(data);
}
public static T DeserializeObject<T>(string json)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Deserialize<T>(json);
}
// Using Json.NET (Newtonsoft.Json)
public static string ToJson<T>(T data)
{
return JsonConvert.SerializeObject(data);
}
public static T FromJson<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
}
XML Serialization Helper
Helper class for XML serialization.
using System.IO;
using System.Xml.Serialization;
public static class XmlUtility
{
public static string SerializeToXml<T>(T data) where T : new()
{
XmlSerializer xmlSerializer = new XmlSerializer(data.GetType());
using (MemoryStream ms = new MemoryStream())
{
xmlSerializer.Serialize(ms, data);
ms.Position = 0;
using (StreamReader reader = new StreamReader(ms))
return reader.ReadToEnd();
}
}
public static T DeserializeFromXml<T>(string xml) where T : new()
{
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(ms);
}
}
public static T LoadFromXmlFile<T>(string filePath) where T : new()
{
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(fs);
}
}
}
Image Processing Example
Basic image drawing and manipulation.
using System.Drawing;
using System.Drawing.Imaging;
public static void CreateImageWithText()
{
using (Bitmap bmp = new Bitmap(300, 100))
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
g.DrawRectangle(Pens.Black, new Rectangle(0, 0, 299, 99));
g.DrawString("Sample Text", new Font("Arial", 14), Brushes.Red, new PointF(10, 10));
string savePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "output.jpg");
bmp.Save(savePath, ImageFormat.Jpeg);
}
}