ZetCode

C# FileShare Enum

last modified April 20, 2025

This tutorial explains how to use the FileShare enum in C# to control file sharing behavior when opening files. FileShare determines how other processes can access the same file.

The FileShare enum specifies the level of access other streams can have to the same file. It is used when opening files with FileStream or similar classes.

FileShare is crucial for multi-process file access scenarios. It helps prevent file access conflicts and enables controlled sharing.

Basic FileShare Example

This example demonstrates using FileShare.None to prevent any other access to the file while it's open. This is the most restrictive mode.

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = "test.txt";
        
        try
        {
            // Open file with exclusive access
            using (var fs = new FileStream(filePath, 
                   FileMode.OpenOrCreate, 
                   FileAccess.ReadWrite, 
                   FileShare.None))
            {
                Console.WriteLine("File opened exclusively. Try opening in another process.");
                Console.ReadLine();
            }
        }
        catch (IOException ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

When FileShare.None is used, any attempt to open the file from another process will fail until the first process closes it. The example creates a FileStream with FileShare.None, which means no other process can access the file while it's open.

If you try to open the file in another program while this code is running, you'll get an access denied error. This demonstrates how to lock a file completely during sensitive operations. The using statement ensures the file is properly closed when done.

FileShare.Read Example

This example shows how to allow other processes to read the file while you have it open. FileShare.Read permits concurrent read access.

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = "shared.txt";
        File.WriteAllText(filePath, "Sample content");
        
        // Open file allowing others to read it
        using (var fs = new FileStream(filePath, 
               FileMode.Open, 
               FileAccess.ReadWrite, 
               FileShare.Read))
        {
            Console.WriteLine("File opened with FileShare.Read");
            Console.WriteLine("Other processes can read this file now");
            Console.ReadLine();
        }
    }
}

FileShare.Read allows other processes to open the file for reading but not for writing. In this example, the file is opened with FileShare.Read, which means other processes can simultaneously open the file for reading but cannot modify it.

This is useful when you need to ensure data consistency while allowing read-only access to other applications. The file remains locked for writing until the original process closes it. This mode is common in read-heavy scenarios where multiple readers are acceptable.

FileShare.Write Example

This example demonstrates FileShare.Write, which allows other processes to write to the file while you have it open. Use with caution.

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = "writable.txt";
        File.WriteAllText(filePath, "Initial content");
        
        // Open file allowing others to write to it
        using (var fs = new FileStream(filePath, 
               FileMode.Open, 
               FileAccess.Read, 
               FileShare.Write))
        {
            Console.WriteLine("File opened with FileShare.Write");
            Console.WriteLine("Other processes can write to this file now");
            
            // Read and display initial content
            using (var reader = new StreamReader(fs))
            {
                Console.WriteLine($"Current content: {reader.ReadToEnd()}");
            }
            
            Console.ReadLine();
        }
    }
}

FileShare.Write permits other processes to write to the file while you have it open. This example opens the file with FileShare.Write, allowing other processes to modify the file concurrently.

Note that we're only reading the file (FileAccess.Read) while allowing others to write. This can lead to race conditions if not managed properly. The example shows the initial content, but this might change if another process writes to the file. This mode is useful in specific scenarios like log file monitoring.

FileShare.ReadWrite Example

This example shows FileShare.ReadWrite, which allows both reading and writing by other processes. This is the most permissive sharing mode.

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = "shared_rw.txt";
        File.WriteAllText(filePath, "Initial content");
        
        // Open file allowing full shared access
        using (var fs = new FileStream(filePath, 
               FileMode.Open, 
               FileAccess.ReadWrite, 
               FileShare.ReadWrite))
        {
            Console.WriteLine("File opened with FileShare.ReadWrite");
            Console.WriteLine("Others can both read and write this file");
            
            // Demonstrate writing
            using (var writer = new StreamWriter(fs))
            {
                writer.WriteLine("New content added");
                writer.Flush();
            }
            
            Console.ReadLine();
        }
    }
}

FileShare.ReadWrite allows complete shared access to the file. This example demonstrates opening a file with full sharing enabled, meaning other processes can both read from and write to the file simultaneously.

The code writes new content to the file while allowing other processes to do the same. This mode requires careful coordination between processes to avoid data corruption. It's typically used in scenarios where multiple processes need to collaborate on the same file with proper synchronization.

FileShare.Delete Example

This example demonstrates FileShare.Delete, which allows other processes to delete the file while you have it open. The file is actually deleted only when all handles are closed.

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = "deletable.txt";
        File.WriteAllText(filePath, "Sample content");
        
        // Open file allowing delete operation
        using (var fs = new FileStream(filePath, 
               FileMode.Open, 
               FileAccess.Read, 
               FileShare.Delete))
        {
            Console.WriteLine("File opened with FileShare.Delete");
            Console.WriteLine("Try deleting this file in Explorer");
            Console.ReadLine();
            
            // Check if file still exists
            Console.WriteLine($"File exists after sharing for delete: {File.Exists(filePath)}");
        }
        
        // Now check if file was actually deleted
        Console.WriteLine($"File exists after closing: {File.Exists(filePath)}");
    }
}

FileShare.Delete allows the file to be marked for deletion while open. In this example, the file is opened with FileShare.Delete, which means another process can request its deletion.

The actual deletion occurs only when all handles to the file are closed. The example demonstrates this by checking File.Exists at different stages. This is useful for temporary files or when implementing file replacement patterns where a new version needs to replace an existing one.

Combining FileShare Flags Example

FileShare flags can be combined using bitwise OR. This example shows how to allow both reading and deletion simultaneously.

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = "combo.txt";
        File.WriteAllText(filePath, "Combined sharing example");
        
        // Combine Read and Delete sharing modes
        using (var fs = new FileStream(filePath, 
               FileMode.Open, 
               FileAccess.ReadWrite, 
               FileShare.Read | FileShare.Delete))
        {
            Console.WriteLine("File opened with Read + Delete sharing");
            Console.WriteLine("Others can read or delete this file");
            
            // Write some data
            using (var writer = new StreamWriter(fs))
            {
                writer.WriteLine("Additional content");
                writer.Flush();
            }
            
            Console.ReadLine();
        }
    }
}

FileShare flags are bit flags that can be combined. This example combines FileShare.Read and FileShare.Delete to allow both operations concurrently. The file can be read by other processes and can also be marked for deletion.

This combination is useful in scenarios where you want to allow readers while also permitting cleanup operations. The bitwise OR operator (|) combines the flags. Multiple flags can be combined this way to create precise sharing behavior for different use cases.

Real-world FileShare Scenario

This example demonstrates a practical use of FileShare in a logging system where multiple processes might need to write to the same log file.

Program.cs
using System;
using System.IO;
using System.Threading;

class Program
{
    static void Main()
    {
        string logPath = "application.log";
        
        // Simulate multiple processes writing to log
        for (int i = 0; i < 3; i++)
        {
            new Thread(() =>  WriteToLog(logPath, $"Process {Thread.CurrentThread.ManagedThreadId}")).Start();
        }
        
        Thread.Sleep(3000); // Let threads work
        Console.WriteLine("Log content:");
        Console.WriteLine(File.ReadAllText(logPath));
    }
    
    static void WriteToLog(string path, string processName)
    {
        for (int i = 0; i < 5; i++)
        {
            try
            {
                // Allow read and write sharing
                using (var fs = new FileStream(path, 
                       FileMode.Append, 
                       FileAccess.Write, 
                       FileShare.ReadWrite))
                using (var writer = new StreamWriter(fs))
                {
                    writer.WriteLine($"{DateTime.Now}: {processName} - Message {i}");
                    writer.Flush();
                    Thread.Sleep(100); // Simulate work
                }
            }
            catch (IOException ex)
            {
                Console.WriteLine($"{processName} error: {ex.Message}");
            }
        }
    }
}

This example simulates multiple processes writing to a shared log file. FileShare.ReadWrite allows concurrent access while FileMode.Append ensures thread-safe appending. Each "process" (simulated by threads) writes several messages to the log file with timestamps.

The FileShare.ReadWrite mode allows other processes to both read and write to the file, while FileMode.Append automatically seeks to the end of file for writing. This combination is commonly used in logging systems where multiple processes need to log to the same file without corrupting data. The example includes basic error handling for IO exceptions.

Source

FileShare Enum Documentation

This tutorial covered using the FileShare enum in C# to control file sharing behavior, with examples ranging from exclusive access to complex sharing scenarios.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.