.NET HELP

FileStream C# (How It Works For Developers)

Jordi Bardia
Jordi Bardia
October 24, 2024
Share:

This article will focus on the FileStream class in C# and how it helps you perform read and write operations on files. We'll explore practical examples, understand how the FileStream works at its core, and learn how to manage file data efficiently. This guide is aimed at those new to file handling in C#, so the language will remain beginner-friendly while providing detailed instructions on working with files in C# and an introduction to the IronPDF library as well.

What is FileStream?

The FileStream class in C# provides a way to handle files using bytes. It works with read and write operations on files, allowing you to interact with file contents directly. This is particularly useful when working with files for input/output tasks, especially when manipulating byte arrays.

FileStream Use Cases

FileStream is ideal for:

  • Reading and writing binary data directly from or to files.
  • Handling large files efficiently.
  • Performing asynchronous file operations.
  • Managing system resources by efficiently using memory.

Basic Example

Here's a simple example to open a file, write data, and then read it using FileStream:

using System;
using System.IO;
public static void Main()
{
    string path = "example.txt";
    // Creating a FileStream object to handle the file. The file handle is acquired here.
    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        byte[] data = System.Text.Encoding.UTF8.GetBytes("Hello, FileStream!");
        fileStream.Write(data, 0, data.Length);
    }
    // Read from the file
    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        byte[] buffer = new byte[1024];
        int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
        string text = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine(text);
    }
}
using System;
using System.IO;
public static void Main()
{
    string path = "example.txt";
    // Creating a FileStream object to handle the file. The file handle is acquired here.
    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        byte[] data = System.Text.Encoding.UTF8.GetBytes("Hello, FileStream!");
        fileStream.Write(data, 0, data.Length);
    }
    // Read from the file
    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        byte[] buffer = new byte[1024];
        int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
        string text = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine(text);
    }
}

This example demonstrates creating a FileStream object to handle file read and write operations. The FileStream class reads and writes bytes directly, making it suitable for handling large files or binary data. We used Encoding to convert between text and bytes.

Writing Data with FileStream

To write data to a file, you'll use the Write method. Here's an example that explains how it works in more detail:

using System;
using System.IO;
public static void Main()
{
    string path = "output.txt";
    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes("Writing data to FileStream.");
        int offset = 0;
        int count = buffer.Length;
        // Writing data to the file
        fileStream.Write(buffer, offset, count);
    }
}
using System;
using System.IO;
public static void Main()
{
    string path = "output.txt";
    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes("Writing data to FileStream.");
        int offset = 0;
        int count = buffer.Length;
        // Writing data to the file
        fileStream.Write(buffer, offset, count);
    }
}

In this code, we convert a string to a byte array using UTF8 encoding. The Write method writes the byte array to the file starting from the current position (determined by the offset) and writing the specified number of bytes.

  • FileMode.Create creates a new file, overwriting any existing file with the same name.
  • FileAccess.Write grants write permissions to the FileStream.

Reading Data with FileStream

Now, let's explore how to read data from a file using FileStream.

using System;
using System.IO;
public static void Main()
{
    // File path
    string path = "output.txt";
    // File Stream Object
    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        byte[] buffer = new byte[1024];
        int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
    // Output Stream
        string output = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine(output);
    }
}
using System;
using System.IO;
public static void Main()
{
    // File path
    string path = "output.txt";
    // File Stream Object
    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        byte[] buffer = new byte[1024];
        int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
    // Output Stream
        string output = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine(output);
    }
}

In this example:

  • FileMode.Open opens an existing file.
  • The Read method reads a specified number of bytes (based on buffer size) and stores them in the byte array buffer.
  • We use Encoding.UTF8.GetString to convert the byte data back to a string.

Managing File Access with FileStream

The FileStream class controls files' access, allowing for fine-tuned file handles and system resources management. When using FileStream, it's vital to ensure the stream is properly disposed of after use, either by calling Close() manually or using the statement that automatically disposes of the stream.

Handling File Position

Every time you read or write to a file, the FileStream keeps track of the current position within the file. You can access this position using the Position property:

fileStream.Position = 0; // Move to the beginning of the file
fileStream.Position = 0; // Move to the beginning of the file

Using FileStream for Asynchronous Operations

FileStream can be used for asynchronous read and write operations, improving performance by allowing other processes to run while the file operations are performed. Here's a basic example of asynchronous reading:

using System;
using System.IO;
using System.Threading.Tasks;
public static async Task Main()
{
    // Specified Path
    string path = "output.txt";
    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None, 4096, true))
    {
        byte[] buffer = new byte[1024];
        int bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length);
        string result = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine(result);
    }
}
using System;
using System.IO;
using System.Threading.Tasks;
public static async Task Main()
{
    // Specified Path
    string path = "output.txt";
    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None, 4096, true))
    {
        byte[] buffer = new byte[1024];
        int bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length);
        string result = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine(result);
    }
}

The ReadAsync method reads the data asynchronously. The FileAccess.Read and FileMode.Open parameters control how the file is accessed.

Example of Handling Exceptions

When working with FileStream, handling exceptions is essential to avoid runtime errors and properly manage system resources. Here's a pattern for handling exceptions when reading or writing to files:

using System;
using System.IO;
public static void Main()
{
    string path = "nonexistentfile.txt";
    try
    {
        using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
        {
            byte[] buffer = new byte[1024];
            int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
            Console.WriteLine("Bytes Read: " + bytesRead);
        }
    }
    catch (FileNotFoundException e)
    {
        Console.WriteLine($"Exception: {e.Message}");
    }
}
using System;
using System.IO;
public static void Main()
{
    string path = "nonexistentfile.txt";
    try
    {
        using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
        {
            byte[] buffer = new byte[1024];
            int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
            Console.WriteLine("Bytes Read: " + bytesRead);
        }
    }
    catch (FileNotFoundException e)
    {
        Console.WriteLine($"Exception: {e.Message}");
    }
}

Buffering and Performance

The FileStream class includes a buffering mechanism that allows for faster performance, especially when working with large files. Using a buffer, data is temporarily stored in memory, reducing the need for constant disk access.

using System;
using System.IO;
public static void Main()
{
    string path = "bufferedfile.txt";
    byte[] data = System.Text.Encoding.UTF8.GetBytes("Buffered FileStream example.");
    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.WriteThrough))
    {
        fileStream.Write(data, 0, data.Length);
    }
}
using System;
using System.IO;
public static void Main()
{
    string path = "bufferedfile.txt";
    byte[] data = System.Text.Encoding.UTF8.GetBytes("Buffered FileStream example.");
    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.WriteThrough))
    {
        fileStream.Write(data, 0, data.Length);
    }
}

Here, FileOptions.WriteThrough ensures that data is written directly to the file, bypassing additional buffering. However, you can control the buffer size for performance tuning.

Introducing IronPDF

FileStream C# (How It Works For Developers): Figure 1 - IronPDF: The C# PDF Library

IronPDF is a robust C# PDF library for creating, editing, and manipulating PDF documents within .NET applications. Developers can generate PDFs from various inputs such as HTML, images, and even raw text using IronPDF. With features like watermarking, merging, splitting, and password protection, IronPDF is ideal for web and desktop applications with precise control over PDF output.

IronPDF with FileStream

Here's an example of generating a PDF using IronPDF and saving it to a FileStream. This demonstrates how IronPDF integrates smoothly with FileStream, allowing developers to programmatically control the creation and saving of PDFs.

using System;
using System.IO;
using IronPdf;
public static void Main()
{
    // Define the file path
    string path = "output.pdf";
    // Create an HTML string that we want to convert to PDF
    var htmlContent = "<h1>IronPDF Example</h1><p>This PDF was generated using IronPDF and saved with FileStream.</p>";
    // Initialize IronPDF's ChromePdfRenderer to render HTML as PDF
    var renderer = new ChromePdfRenderer();
    // Generate the PDF from the HTML string
    var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
    // Use FileStream to save the generated PDF
    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        pdfDocument.SaveAs(fileStream);
    }
    Console.WriteLine("PDF created and saved successfully.");
}
using System;
using System.IO;
using IronPdf;
public static void Main()
{
    // Define the file path
    string path = "output.pdf";
    // Create an HTML string that we want to convert to PDF
    var htmlContent = "<h1>IronPDF Example</h1><p>This PDF was generated using IronPDF and saved with FileStream.</p>";
    // Initialize IronPDF's ChromePdfRenderer to render HTML as PDF
    var renderer = new ChromePdfRenderer();
    // Generate the PDF from the HTML string
    var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
    // Use FileStream to save the generated PDF
    using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        pdfDocument.SaveAs(fileStream);
    }
    Console.WriteLine("PDF created and saved successfully.");
}

Conclusion

FileStream C# (How It Works For Developers): Figure 2 - IronPDF Licensing Page

The FileStream class in C# offers powerful functionality for managing file input and output. It allows developers to read and write data efficiently, control the current position within a file, and work asynchronously by understanding how byte arrays, file paths, and stream handling work together. Using FileStream in combination with IronPDF provides developers with the flexibility to handle PDFs efficiently within .NET applications. Whether you're generating reports, saving files, or handling dynamic content, this combination offers fine control over creating and storing PDF documents.

IronPDF offers a free trial and a $749 licensing fee, making it a competitive solution for professional PDF generation needs.

Jordi Bardia
Software Engineer
Jordi is most proficient in Python, C# and C++, when he isn’t leveraging his skills at Iron Software; he’s game programming. Sharing responsibilities for product testing, product development and research, Jordi adds immense value to continual product improvement. The varied experience keeps him challenged and engaged, and he says it’s one of his favorite aspects of working with Iron Software. Jordi grew up in Miami, Florida and studied Computer Science and Statistics at University of Florida.
< PREVIOUS
C# Initialize List (How It Works For Developers)
NEXT >
C# Init Keyword (How It Works For Developers)