DEV Community

mohamed Tayel
mohamed Tayel

Posted on

Mastering C# Fundamentals :Adding File Handling

Meta Description:Learn how to enhance your C# book management application with file handling capabilities using the System.IO namespace. This article guides you step-by-step through saving, loading, and managing book data in files, making your application more practical by persisting data across sessions

In this article, we’ll dive into the concept of file handling in C# and learn how to use the System.IO namespace to interact with files and directories. We will extend our existing book management application to include features for storing book information in a file. This makes our application more practical, allowing it to persist data beyond a single session.

Many applications need to work with files. For instance, a word processing application saves text files, an image editor stores images, and even custom business applications like ours can benefit from using files to store user-entered information. In our book management application, we'll store the registered books in a text file that we can read back when the application restarts.

Let’s start by adding the capability to check if the file for saving books exists and create it if necessary. We will use classes like Directory, File, and Path from the System.IO namespace, which provides us with the necessary tools for working with files, directories, and paths.

Step 1: Modifying CheckForExistingBookFile Method

We will start by modifying the CheckForExistingBookFile method in the Utilities class to ensure that a directory and file are set up for our book data.

Here’s the updated version of the Utilities.cs file, which includes the CheckForExistingBookFile method:

using System;
using System.Collections.Generic;
using System.IO;

namespace BookManagementApp
{
    public static class Utilities
    {
        private static string directoryPath = @"D:\data\BookManagementApp";
        private static string fileName = "books.txt";

        public static void CheckForExistingBookFile()
        {
            string filePath = $"{directoryPath}\\{fileName}";

            // Check if the file already exists
            bool fileExists = File.Exists(filePath);

            if (fileExists)
            {
                Console.WriteLine("Book data file already exists.");
            }
            else
            {
                // If directory doesn't exist, create it
                if (!Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Directory created for storing book data.");
                    Console.ResetColor();
                }

                Console.WriteLine("Book data file does not exist yet. It will be created when saving data.");
            }
        }

        public static void RegisterBook(List<Book> books)
        {
            Console.WriteLine("\nRegister a New Book:");

            // Collecting book details from the user
            Console.Write("Enter Title: ");
            string title = Console.ReadLine();

            Console.Write("Enter Author: ");
            string author = Console.ReadLine();

            Console.Write("Enter Genre (e.g., Fiction, Mystery): ");
            string genre = Console.ReadLine();

            Console.Write("Enter Publication Date (yyyy-mm-dd): ");
            DateTime publicationDate;
            while (!DateTime.TryParse(Console.ReadLine(), out publicationDate))
            {
                Console.Write("Invalid date format. Enter Publication Date (yyyy-mm-dd): ");
            }

            // Creating a new Book instance and adding it to the list
            Book newBook = new Book(title, author, genre, publicationDate);
            books.Add(newBook);

            Console.WriteLine("Book registered successfully!");
        }

        public static void ViewBooks(List<Book> books)
        {
            Console.WriteLine("\nList of Registered Books:");

            if (books.Count == 0)
            {
                Console.WriteLine("No books registered.");
            }
            else
            {
                foreach (var book in books)
                {
                    book.DisplayBookDetails(); // Display each book's details.
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
Explanation
  • Directory and File Path Setup:

    • We defined two static fields, directoryPath and fileName, to store the directory and file name.
    • The directoryPath is set to "D:\data\BookManagementApp" and the file is called "books.txt".
  • File Check Logic:

    • We first concatenate the directory and file name using $"{directoryPath}\\{fileName}".
    • We use File.Exists(filePath) to check if the file exists.
    • If the file doesn’t exist, we check if the directory exists. If not, we create it using Directory.CreateDirectory(directoryPath) and print a message to notify the user.

Step 2: Saving Books to a File

Next, let’s add the capability to save books to a file. We'll add a new method in the Utilities.cs class called SaveBooksToFile:

public static void SaveBooksToFile(List<Book> books)
{
    string filePath = $"{directoryPath}\\{fileName}";

    // Writing book data to the file
    using (StreamWriter writer = new StreamWriter(filePath))
    {
        foreach (var book in books)
        {
            writer.WriteLine($"{book.Title}|{book.Author}|{book.Genre}|{book.PublicationDate:yyyy-MM-dd}");
        }
    }

    Console.WriteLine("Books saved to file successfully.");
}
Enter fullscreen mode Exit fullscreen mode
Explanation
  • SaveBooksToFile():
    • We use the StreamWriter class to write the book data to the file.
    • We iterate over the list of books and write each book’s details in a formatted way, using a pipe (|) as a delimiter.

Step 3: Loading Books from a File

We also need to be able to load the books back from the file when the application starts. Here’s the LoadBooksFromFile method:

public static void LoadBooksFromFile(List<Book> books)
{
    string filePath = $"{directoryPath}\\{fileName}";

    // If the file doesn't exist, there's nothing to load
    if (!File.Exists(filePath))
    {
        Console.WriteLine("No book data file found to load.");
        return;
    }

    // Reading book data from the file
    using (StreamReader reader = new StreamReader(filePath))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            string[] parts = line.Split('|');
            if (parts.Length == 4)
            {
                string title = parts[0];
                string author = parts[1];
                string genre = parts[2];
                DateTime publicationDate = DateTime.Parse(parts[3]);

                Book book = new Book(title, author, genre, publicationDate);
                books.Add(book);
            }
        }
    }

    Console.WriteLine("Books loaded from file successfully.");
}
Enter fullscreen mode Exit fullscreen mode
Explanation
  • LoadBooksFromFile():
    • If the book file doesn’t exist, the method simply returns.
    • If the file does exist, we read each line, split it using the delimiter (|), and create a new Book instance for each entry.
    • The newly created Book instances are added to the list of books.

Step 4: Updating the Main Program Menu

Now, let’s update our Program.cs to add options 3 and 4 to save and load books:

switch (userSelection)
{
    case "1":
        Utilities.RegisterBook(books);
        break;
    case "2":
        Utilities.ViewBooks(books);
        break;
    case "3":
        Utilities.SaveBooksToFile(books);
        break;
    case "4":
        Utilities.LoadBooksFromFile(books);
        break;
    case "9":
        running = false;
        break;
    default:
        Console.WriteLine("Invalid selection, please try again.");
        break;
}
Enter fullscreen mode Exit fullscreen mode

Testing the Application

Here’s a quick overview of how the application works now:

  1. Registering a Book: You can register a book by entering its title, author, genre, and publication date. The book details are stored in memory.
  2. Saving Books: When you choose option 3, the books are saved to "D:\data\BookManagementApp\books.txt".
  3. Loading Books: When you restart the application and select option 4, it will load the books from the file.
  4. Viewing Books: You can view all the registered books by selecting option 2.

Conclusion

In this article, we have extended our book management application to handle file operations using the System.IO namespace. We’ve added features to:

  • Check for existing files and directories.
  • Save books to a file.
  • Load books from a file.

These new capabilities make our application more practical by persisting the book data between application runs. In future articles, we can expand this even further, perhaps adding more complex operations or moving on to database storage.

Stay tuned as we continue improving our book management tool and adding new capabilities!

Top comments (0)