ZetCode

C# FileAccess 枚举

最后修改于 2025 年 4 月 20 日

本教程解释了如何在 C# 中使用 FileAccess 枚举来控制文件访问权限。FileAccess 指定对文件的读取、写入或读/写访问权限。

FileAccess 枚举是 System.IO 命名空间的一部分。它定义了对文件的读取、写入或读/写访问的常量。这些权限在使用 FileStream 或类似类打开文件时使用。

FileAccess 通过显式声明预期的访问模式来帮助确保正确的文件处理。这可以防止意外修改并提高文件操作的安全性。

FileAccess 基本示例

此示例演示如何使用 FileAccess.Read 以只读访问权限打开文件。我们将读取文本文件的内容。

Program.cs
using System;
using System.IO;
using System.Text;

class Program
{
    static void Main()
    {
        string path = "example.txt";
        File.WriteAllText(path, "Hello FileAccess!");
        
        using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
        using (var reader = new StreamReader(fs, Encoding.UTF8))
        {
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        }
    }
}

该代码创建一个具有写入访问权限的文件,然后以只读权限打开它。FileStream 构造函数将 FileAccess.Read 作为第三个参数。这确保了该文件只能被读取,而不能被修改。

StreamReader 读取整个文件内容。尝试写入此流将引发异常。这演示了 FileAccess 如何在流级别强制执行访问限制。

使用 FileAccess.Write 写入文件

此示例演示如何使用 FileAccess.Write 以只写访问权限打开文件。我们将文本追加到现有文件。

Program.cs
using System;
using System.IO;
using System.Text;

class Program
{
    static void Main()
    {
        string path = "log.txt";
        
        using (var fs = new FileStream(path, FileMode.Append, FileAccess.Write))
        using (var writer = new StreamWriter(fs, Encoding.UTF8))
        {
            writer.WriteLine($"{DateTime.Now}: Log entry added");
        }
        
        Console.WriteLine("Log entry written successfully");
    }
}

FileStream 在追加模式下以 FileAccess.Write 权限打开。这允许写入文件,但阻止从中读取。 StreamWriter 添加一个带时间戳的日志条目。

尝试从此流读取将引发异常。这演示了 FileAccess.Write 如何将操作限制为仅写入。它对于只需要追加数据的日志文件很有用。

使用 FileAccess.ReadWrite 进行读/写访问

此示例演示了使用 FileAccess.ReadWrite 进行完全读/写访问。我们将就地修改配置文件。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = "config.dat";
        File.WriteAllText(path, "Initial configuration");
        
        using (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
        {
            // Read existing content
            byte[] buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            string content = System.Text.Encoding.UTF8.GetString(buffer);
            Console.WriteLine("Original: " + content);
            
            // Modify content
            fs.Position = 0;
            string newContent = "Modified configuration";
            byte[] newData = System.Text.Encoding.UTF8.GetBytes(newContent);
            fs.Write(newData, 0, newData.Length);
            fs.SetLength(newData.Length);
        }
        
        Console.WriteLine("File updated successfully");
    }
}

该文件以 FileAccess.ReadWrite 打开,允许读取和写入操作。我们首先读取现有内容,然后用新数据覆盖它。 Position 属性重置为写入的开头。

当您需要读取和修改文件的内容时,FileAccess.ReadWrite 非常有用。该示例展示了如何在读取和写入操作之间切换时正确处理文件位置。

将 FileAccess 与 FileShare 结合使用

此示例演示了如何将 FileAccess 与 FileShare 结合使用来控制其他进程如何访问文件。我们将创建一个具有共享读取访问权限的文件。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = "shared.txt";
        
        using (var fs = new FileStream(
            path,
            FileMode.Create,
            FileAccess.ReadWrite,
            FileShare.Read))
        {
            // Write initial data
            byte[] data = System.Text.Encoding.UTF8.GetBytes("Shared content");
            fs.Write(data, 0, data.Length);
            
            // Simulate another process reading the file
            try
            {
                using (var sharedFs = new FileStream(
                    path,
                    FileMode.Open,
                    FileAccess.Read,
                    FileShare.Read))
                {
                    Console.WriteLine("File opened successfully in another process");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
        }
    }
}

FileStream 使用 FileAccess.ReadWrite 和 FileShare.Read 创建。这允许其他进程打开该文件进行读取,但不能进行写入。该示例模拟了另一个进程访问该文件。

FileAccess 和 FileShare 的结合使用提供了对多进程场景中文件共享的细粒度控制。这对于需要在进程之间协调文件访问的应用程序特别有用。

处理访问被拒绝错误

此示例演示了在文件访问被拒绝时如何进行正确的错误处理。我们将尝试使用冲突的权限打开文件。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = "locked.txt";
        File.WriteAllText(path, "Test content");
        
        // First process locks the file
        using (var lockedFs = new FileStream(
            path,
            FileMode.Open,
            FileAccess.Read,
            FileShare.None))
        {
            Console.WriteLine("File locked by first process");
            
            try
            {
                // Second process tries to access
                using (var fs = new FileStream(
                    path,
                    FileMode.Open,
                    FileAccess.Read))
                {
                    Console.WriteLine("This won't be reached");
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine("Access denied: " + ex.Message);
            }
            catch (IOException ex)
            {
                Console.WriteLine("IO Error: " + ex.Message);
            }
        }
    }
}

第一个 FileStream 使用 FileShare.None 打开文件,阻止其他访问。第二次尝试打开该文件会引发异常。我们捕获 UnauthorizedAccessExceptionIOException 以进行强大的错误处理。

此示例展示了如何在实际应用程序中正确处理访问冲突。 try-catch 块确保应用程序可以从访问被拒绝的情况中优雅地恢复。

FileAccess 与 BinaryReader/Writer

此示例演示了如何将 FileAccess 与 BinaryReader 和 BinaryWriter 结合使用,以进行高效的二进制文件操作。

Program.cs
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = "data.bin";
        
        // Write binary data
        using (var fs = new FileStream(
            path,
            FileMode.Create,
            FileAccess.Write))
        using (var writer = new BinaryWriter(fs))
        {
            writer.Write(42);
            writer.Write(3.14159);
            writer.Write(true);
        }
        
        // Read binary data
        using (var fs = new FileStream(
            path,
            FileMode.Open,
            FileAccess.Read))
        using (var reader = new BinaryReader(fs))
        {
            int number = reader.ReadInt32();
            double pi = reader.ReadDouble();
            bool flag = reader.ReadBoolean();
            
            Console.WriteLine($"Read: {number}, {pi}, {flag}");
        }
    }
}

二进制文件首先以只写访问权限创建,然后以只读访问权限打开。 BinaryWriter 和 BinaryReader 使用指定的 FileAccess 权限工作。这确保了对二进制文件的正确访问控制。

该示例展示了 FileAccess 如何与二进制文件操作无缝集成。写入和读取操作的分离演示了干净的访问模式分离。

使用 FileAccess 的异步文件操作

此示例演示了如何在 I/O 密集型应用程序中使用 FileAccess 进行异步文件操作,以获得更好的性能。

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

class Program
{
    static async Task Main()
    {
        string path = "async.txt";
        
        // Asynchronous write
        using (var fs = new FileStream(
            path,
            FileMode.Create,
            FileAccess.Write,
            FileShare.None,
            4096,
            FileOptions.Asynchronous))
        using (var writer = new StreamWriter(fs))
        {
            await writer.WriteLineAsync("Asynchronous line 1");
            await writer.WriteLineAsync("Asynchronous line 2");
        }
        
        // Asynchronous read
        using (var fs = new FileStream(
            path,
            FileMode.Open,
            FileAccess.Read,
            FileShare.Read,
            4096,
            FileOptions.Asynchronous))
        using (var reader = new StreamReader(fs))
        {
            string content = await reader.ReadToEndAsync();
            Console.WriteLine("File content:");
            Console.WriteLine(content);
        }
    }
}

FileStream 配置为使用 FileOptions 进行异步操作。 FileAccess 控制访问类型,而操作异步执行。这结合了访问控制和性能优势。

该示例演示了使用 FileAccess 的现代 async/await 模式。对于处理大型文件或许多并发操作的应用程序,异步 I/O 特别有价值。

来源

FileAccess 枚举文档

本教程介绍了如何在 C# 中使用 FileAccess 枚举来控制文件权限,包括使用各种文件处理类的读取、写入和读/写操作。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。到目前为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 C# 教程