C# -

File I/O

File Input/Output (I/O) operations are essential for reading from and writing to files in C#. This tutorial will cover the basics of file I/O, various techniques, best practices, and advanced concepts.


1. Introduction to File I/O

File I/O in C# involves reading from and writing to files using various classes provided in the System.IO namespace. Understanding file I/O is crucial for handling data storage, retrieval, and manipulation.


2. Reading Text Files

Reading text files can be done using the File class and StreamReader class. Here's a basic example:

        
            using System;
using System.IO;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string filePath = "example.txt";

        // Check if file exists
        if (File.Exists(filePath))
        {
            // Read all lines from the file
            string[] lines = File.ReadAllLines(filePath);
            foreach (string line in lines)
            {
                Console.WriteLine(line);
            }
        }
        else
        {
            Console.WriteLine("File does not exist.");
        }
    }
}
        
    

3. Writing Text Files

Writing text files can be accomplished using the File class and StreamWriter class. Here's how:

        
            using System;
using System.IO;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string filePath = "example.txt";
        string[] lines = { "First line", "Second line", "Third line" };

        // Write lines to file
        File.WriteAllLines(filePath, lines);
        Console.WriteLine("Lines written to file.");
    }
}
        
    

4. Reading and Writing Binary Files

Binary file operations can be handled using the BinaryReader and BinaryWriter classes. Here's an example:

        
            using System;
using System.IO;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string filePath = "example.bin";

        // Write binary data
        using (BinaryWriter writer = new BinaryWriter(File.Open(filePath, FileMode.Create)))
        {
            writer.Write(1.25);
            writer.Write("Hello");
            writer.Write(true);
        }

        // Read binary data
        using (BinaryReader reader = new BinaryReader(File.Open(filePath, FileMode.Open)))
        {
            double value = reader.ReadDouble();
            string text = reader.ReadString();
            bool flag = reader.ReadBoolean();

            Console.WriteLine($"Read values: {value}, {text}, {flag}");
        }
    }
}
        
    

5. File Streams

FileStream provides a way to work with files at a lower level. Here's how to use FileStream:

        
            using System;
using System.IO;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string filePath = "example.txt";

        // Write to file using FileStream
        using (FileStream fs = new FileStream(filePath, FileMode.Create))
        {
            byte[] info = new UTF8Encoding(true).GetBytes("This is some text.");
            fs.Write(info, 0, info.Length);
        }

        // Read from file using FileStream
        using (FileStream fs = new FileStream(filePath, FileMode.Open))
        {
            byte[] b = new byte[1024];
            UTF8Encoding temp = new UTF8Encoding(true);

            while (fs.Read(b, 0, b.Length) > 0)
            {
                Console.WriteLine(temp.GetString(b));
            }
        }
    }
}
        
    

6. Working with File Info

The FileInfo class provides properties and methods for working with files. Here's an example:

        
            using System;
using System.IO;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string filePath = "example.txt";

        // Create a FileInfo object
        FileInfo fileInfo = new FileInfo(filePath);

        // Create file if it doesn't exist
        if (!fileInfo.Exists)
        {
            using (StreamWriter sw = fileInfo.CreateText())
            {
                sw.WriteLine("Hello, world!");
            }
        }

        // Display file information
        Console.WriteLine($"File Name: {fileInfo.Name}");
        Console.WriteLine($"File Size: {fileInfo.Length} bytes");
        Console.WriteLine($"File Extension: {fileInfo.Extension}");
        Console.WriteLine($"Last Accessed: {fileInfo.LastAccessTime}");

        // Delete the file
        fileInfo.Delete();
        Console.WriteLine("File deleted.");
    }
}
        
    

7. Working with Directory Info

The DirectoryInfo class allows you to work with directories. Here's how:

        
            using System;
using System.IO;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string dirPath = "exampleDir";

        // Create Directory
        DirectoryInfo dirInfo = new DirectoryInfo(dirPath);
        if (!dirInfo.Exists)
        {
            dirInfo.Create();
            Console.WriteLine("Directory created.");
        }

        // List Directories and Files
        foreach (var dir in dirInfo.GetDirectories())
        {
            Console.WriteLine($"Directory: {dir.Name}");
        }

        foreach (var file in dirInfo.GetFiles())
        {
            Console.WriteLine($"File: {file.Name}");
        }

        // Delete Directory
        dirInfo.Delete(true);
        Console.WriteLine("Directory deleted.");
    }
}
        
    

8. Asynchronous File I/O

Asynchronous file operations can improve the performance of your application. Here's an example:

        
            using System;
using System.IO;
using System.Threading.Tasks;

namespace FileIOExamples;

public class Program
{
    public static async Task Main(string[] args)
    {
        string filePath = "example.txt";

        // Write to file asynchronously
        using (StreamWriter writer = new StreamWriter(filePath))
        {
            await writer.WriteLineAsync("Hello, async world!");
        }

        // Read from file asynchronously
        using (StreamReader reader = new StreamReader(filePath))
        {
            string content = await reader.ReadToEndAsync();
            Console.WriteLine(content);
        }
    }
}
        
    

9. Handling File Paths

The Path class provides methods for manipulating file and directory paths. Here's how to use it:

        
            using System;
using System.IO;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string fullPath = @"C:\\example\\path\\file.txt";

        // Get directory name
        string directoryName = Path.GetDirectoryName(fullPath);
        Console.WriteLine($"Directory Name: {directoryName}");

        // Get file name
        string fileName = Path.GetFileName(fullPath);
        Console.WriteLine($"File Name: {fileName}");

        // Get file extension
        string extension = Path.GetExtension(fullPath);
        Console.WriteLine($"File Extension: {extension}");

        // Combine paths
        string combinedPath = Path.Combine("C:\\example", "path", "file.txt");
        Console.WriteLine($"Combined Path: {combinedPath}");
    }
}
        
    

10. File and Directory Operations

Common file and directory operations include creating, copying, moving, and deleting files and directories. Here's an example:

        
            using System;
using System.IO;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string filePath = "example.txt";
        string destFilePath = "exampleCopy.txt";

        // Create a file
        File.WriteAllText(filePath, "Hello, world!");

        // Copy the file
        File.Copy(filePath, destFilePath, true);
        Console.WriteLine("File copied.");

        // Move the file
        string movedFilePath = "exampleMoved.txt";
        File.Move(destFilePath, movedFilePath);
        Console.WriteLine("File moved.");

        // Delete the file
        File.Delete(movedFilePath);
        Console.WriteLine("File deleted.");
    }
}
        
    

11. File and Directory Permissions

Managing file and directory permissions is crucial for security. Here's how to handle permissions:

        
            using System;
using System.IO;
using System.Security.AccessControl;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string filePath = "example.txt";
        File.WriteAllText(filePath, "Hello, world!");

        // Get the current ACL
        FileSecurity fileSecurity = File.GetAccessControl(filePath);

        // Add a new rule
        fileSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.Read, AccessControlType.Allow));

        // Apply the new rule
        File.SetAccessControl(filePath, fileSecurity);
        Console.WriteLine("Permissions updated.");
    }
}
        
    

12. Best Practices for File I/O

Here are some best practices for handling file I/O in C#:


13. Advanced File I/O Techniques

Advanced file I/O techniques include working with memory-mapped files, monitoring file system changes, and handling large files. Here's an example:

        
            using System;
using System.IO;
using System.IO.MemoryMappedFiles;

namespace FileIOExamples;

public class Program
{
    public static void Main(string[] args)
    {
        string filePath = "example.bin";
        long offset = 0x10000000; // 256 megabytes
        long length = 0x20000000; // 512 megabytes

        // Create the memory-mapped file
        using (var mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.Create, "mapName", length))
        {
            // Create a random access view
            using (var accessor = mmf.CreateViewAccessor(offset, length))
            {
                int colorSize = 4;
                for (long i = 0; i < length; i += colorSize)
                {
                    accessor.Write(i, 0xFFFF00FF); // Write a color value
                }
            }
        }

        Console.WriteLine("Memory-mapped file created and written.");
    }
}
        
    


14. Conclusion

File I/O is a critical aspect of many applications. By understanding and applying the various techniques and best practices, you can effectively read from and write to files, manage file paths, and handle file system operations in your C# applications.