System.IO Namespace
The System.IO namespace provides types that allow you to read and write files and data streams, and to interact with the file system.
Overview
File I/O (Input/Output) is a fundamental aspect of most applications. The System.IO namespace in .NET offers a rich set of classes and methods to abstract away the complexities of interacting with the underlying operating system's file system and data streams.
Key features include:
- Working with files and directories.
- Reading from and writing to data streams.
- Handling different data formats (text, binary).
- Path manipulation and file system monitoring.
File Operations
The File class provides static methods for creating, copying, deleting, moving, and opening files. It's often the most straightforward way to perform common file operations.
Commonly used methods:
File.Exists(string path): Checks if a file exists.File.Create(string path): Creates a new file or overwrites an existing one. Returns aFileStream.File.ReadAllText(string path): Reads the entire content of a file as a string.File.WriteAllText(string path, string contents): Writes a string to a file, creating the file if it doesn't exist, or overwriting it if it does.File.Copy(string sourceFileName, string destFileName): Copies an existing file to a new location.File.Move(string sourceFileName, string destFileName): Moves an existing file to a new location.File.Delete(string path): Deletes a file.
Example: Reading and Writing Text
using System;
using System.IO;
public class FileOperations
{
public static void Main(string[] args)
{
string filePath = "myDocument.txt";
string contentToWrite = "Hello, System.IO!";
// Write text to a file
try
{
File.WriteAllText(filePath, contentToWrite);
Console.WriteLine($"Successfully wrote to '{filePath}'");
}
catch (Exception ex)
{
Console.WriteLine($"Error writing to file: {ex.Message}");
}
// Read text from a file
try
{
if (File.Exists(filePath))
{
string fileContent = File.ReadAllText(filePath);
Console.WriteLine($"Content of '{filePath}': {fileContent}");
}
else
{
Console.WriteLine($"File '{filePath}' does not exist.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error reading file: {ex.Message}");
}
}
}
Directory Operations
Similar to the File class, the Directory class provides static methods for creating, moving, and enumerating through directories and subdirectories.
Commonly used methods:
Directory.Exists(string path): Checks if a directory exists.Directory.CreateDirectory(string path): Creates a directory.Directory.GetFiles(string path): Retrieves the names of files in the specified directory.Directory.GetDirectories(string path): Retrieves the names of subdirectories in the specified directory.Directory.Move(string sourceDirName, string destDirName): Moves a directory and its contents.Directory.Delete(string path, bool recursive): Deletes a directory. Setrecursivetotrueto delete the directory and all its contents.
Example: Listing files and directories
using System;
using System.IO;
public class DirectoryOperations
{
public static void Main(string[] args)
{
string targetDirectory = "."; // Current directory
Console.WriteLine($"Files in '{targetDirectory}':");
try
{
string[] files = Directory.GetFiles(targetDirectory);
foreach (string file in files)
{
Console.WriteLine(Path.GetFileName(file));
}
}
catch (Exception ex)
{
Console.WriteLine($"Error listing files: {ex.Message}");
}
Console.WriteLine($"\nDirectories in '{targetDirectory}':");
try
{
string[] directories = Directory.GetDirectories(targetDirectory);
foreach (string dir in directories)
{
Console.WriteLine(Path.GetFileName(dir));
}
}
catch (Exception ex)
{
Console.WriteLine($"Error listing directories: {ex.Message}");
}
}
}
The Path class is also very useful for manipulating file and directory paths in a platform-agnostic way (e.g., Path.Combine(), Path.GetFileName(), Path.GetExtension()).
Streams
Streams represent a sequence of bytes and are fundamental for I/O operations, especially when dealing with large amounts of data or network communication.
Key Stream Classes:
FileStream: Provides a stream for file I/O.MemoryStream: A stream that uses memory instead of a disk file.BufferedStream: Adds buffering to another stream to reduce the number of read/write operations.StreamReader: Reads characters from a byte stream in a particular encoding.StreamWriter: Writes characters to a stream in a particular encoding.
When working with streams, it's crucial to manage resources properly, typically using the using statement to ensure streams are closed and disposed of correctly, even if errors occur.
Example: Using StreamReader and StreamWriter
using System;
using System.IO;
public class StreamExample
{
public static void Main(string[] args)
{
string logFilePath = "app.log";
// Append to a log file using StreamWriter
try
{
using (StreamWriter sw = new StreamWriter(logFilePath, true)) // 'true' for append
{
sw.WriteLine($"{DateTime.Now}: Application started.");
sw.WriteLine("Performing some operations...");
}
Console.WriteLine($"Log entry added to '{logFilePath}'");
}
catch (Exception ex)
{
Console.WriteLine($"Error writing to log: {ex.Message}");
}
// Read the log file using StreamReader
Console.WriteLine($"\nReading log file '{logFilePath}':");
try
{
if (File.Exists(logFilePath))
{
using (StreamReader sr = new StreamReader(logFilePath))
{
string line;
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
else
{
Console.WriteLine("Log file not found.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error reading log: {ex.Message}");
}
}
}
Serialization
Serialization is the process of converting an object into a format that can be stored or transmitted (e.g., a file, a database, or a network stream) and then reconstructed later.
Common Serialization Formats:
- XML Serialization: Uses the
System.Xml.Serializationnamespace. Good for human-readable data. - JSON Serialization: Uses libraries like
Newtonsoft.Json(popular third-party) orSystem.Text.Json(built-in since .NET Core 3.0). Widely used for web APIs. - Binary Serialization: Uses
System.Runtime.Serialization.Formatters.Binary. Efficient but not human-readable and can have versioning issues.
Example (Conceptual using JSON.NET):
While System.IO is about reading and writing, serialization leverages it to store structured data.
using System;
using System.IO;
// Assuming Newtonsoft.Json is added as a NuGet package
using Newtonsoft.Json;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class SerializationExample
{
public static void Main(string[] args)
{
Person person = new Person { Name = "Alice", Age = 30 };
string jsonFilePath = "person.json";
// Serialize to JSON and save to file
try
{
string jsonString = JsonConvert.SerializeObject(person, Formatting.Indented);
File.WriteAllText(jsonFilePath, jsonString);
Console.WriteLine($"Person object serialized to '{jsonFilePath}'");
}
catch (Exception ex)
{
Console.WriteLine($"Error serializing: {ex.Message}");
}
// Deserialize from JSON file
try
{
if (File.Exists(jsonFilePath))
{
string jsonContent = File.ReadAllText(jsonFilePath);
Person deserializedPerson = JsonConvert.DeserializeObject(jsonContent);
Console.WriteLine($"\nDeserialized Person: Name={deserializedPerson.Name}, Age={deserializedPerson.Age}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error deserializing: {ex.Message}");
}
}
}