引言:为什么需要在C#中处理文件系统
\n任何严肃的应用程序迟早都会面临数据保存的需求。无论是配置文件、日志、用户文档还是临时数据——处理文件系统是C#开发人员的基本技能。在本文中,我们将通过实际示例讲解如何使用.NET创建、读取、写入和管理文件与文件夹。您不仅将学习基本操作,还将了解异常处理的最佳实践以及流的使用方法。
\n\n用于处理文件系统的主要类
\n在.NET中,与文件系统交互需要使用命名空间 System.IO 和 System.IO.Enumeration。您将需要以下关键类:
- \n
File— 用于创建、复制、删除和移动文件的静态方法。 \n FileInfo— 用于处理特定文件的实例类(支持相同操作,但需要创建对象)。 \n Directory— 用于处理目录的静态方法。 \n DirectoryInfo— 用于处理目录的实例类。 \n Path— 用于处理路径的工具类(合并、获取扩展名、文件名等)。 \n FileStream— 用于读取/写入字节的低级流。 \n StreamReader/StreamWriter— 用于处理文本的高级包装器。 \n
选择静态方法还是实例类取决于具体场景。如果您只需要执行一次操作,请使用 File 或 Directory。如果计划对同一对象执行多次操作,请创建 FileInfo 或 DirectoryInfo。
创建、读取和写入文件
\n\n1. 创建和写入文本文件
\n将文本写入文件的最简单方法是使用 File.WriteAllText 方法。它会创建文件(或覆盖现有文件)并自动关闭流。
using System.IO;\n\nstring path = @"C:\\temp\\example.txt";\nstring content = "你好,世界!这是一个测试文件。";\n\nFile.WriteAllText(path, content);\nConsole.WriteLine("文件已创建并写入。");\n如果需要在文件末尾追加数据,请使用 File.AppendAllText:
File.AppendAllText(path, "\\n追加的行。");\n\n2. 读取文件
\n要读取整个文本,请使用 File.ReadAllText:
string readContent = File.ReadAllText(path);\nConsole.WriteLine(readContent);\n如果文件很大,最好通过 File.ReadLines 逐行读取(返回 IEnumerable<string>):
foreach (string line in File.ReadLines(path))\n{\n Console.WriteLine(line);\n}\n\n3. 处理二进制文件
\n对于二进制数据(图像、压缩包),请使用 FileStream 或 BinaryReader/BinaryWriter。写入字节数组的示例:
byte[] data = { 0x48, 0x65, 0x6C, 0x6C, 0x6F }; // "Hello"\nFile.WriteAllBytes(@"C:\\temp\\binary.dat", data);\n\nbyte[] readData = File.ReadAllBytes(@"C:\\temp\\binary.dat");\nConsole.WriteLine(BitConverter.ToString(readData)); // 48-65-6C-6C-6F\n\n处理文件夹和管理文件
\n\n1. 创建和删除文件夹
\n可以使用 Directory.CreateDirectory 创建文件夹。该方法会创建路径中所有缺失的文件夹:
string dirPath = @"C:\\temp\\MyApp\\Logs";\nDirectory.CreateDirectory(dirPath);\nConsole.WriteLine("文件夹已创建。");\n删除文件夹(递归删除,包括所有内容):
\nif (Directory.Exists(dirPath))\n{\n Directory.Delete(dirPath, true);\n Console.WriteLine("文件夹已删除。");\n}\n\n2. 复制和移动文件
\n复制文件使用 File.Copy,移动文件使用 File.Move:
string sourceFile = @"C:\\temp\\example.txt";\nstring destFile = @"C:\\temp\\backup\\example.txt";\n\n// 复制文件(如果目标文件存在,第三个参数为 true 则覆盖)\nFile.Copy(sourceFile, destFile, true);\n\n// 移动文件(重命名)\nFile.Move(sourceFile, @"C:\\temp\\moved_example.txt");\n\n使用流进行高效处理
\n对于大文件或需要精细控制时,请使用 FileStream。使用 using 语句自动释放资源:
string filePath = @"C:\\temp\\largefile.dat";\n\n// 写入\nusing (FileStream fs = new FileStream(filePath, FileMode.Create))\n{\n byte[] data = System.Text.Encoding.UTF8.GetBytes("流数据示例");\n fs.Write(data, 0, data.Length);\n}\n\n// 读取\nusing (FileStream fs = new FileStream(filePath, FileMode.Open))\n{\n byte[] buffer = new byte[fs.Length];\n fs.Read(buffer, 0, buffer.Length);\n string text = System.Text.Encoding.UTF8.GetString(buffer);\n Console.WriteLine(text);\n}\n对于文本,更方便的是使用 StreamReader 和 StreamWriter:
using (StreamWriter writer = new StreamWriter(@"C:\\temp\\log.txt", append: true))\n{\n writer.WriteLine($"{DateTime.Now}: 应用程序已启动");\n}\n\nusing (StreamReader reader = new StreamReader(@"C:\\temp\\log.txt"))\n{\n string line;\n while ((line = reader.ReadLine()) != null)\n {\n Console.WriteLine(line);\n }\n}\n\n异常处理:最佳实践
\n处理文件系统时,异常是不可避免的。始终使用 try-catch 块并处理特定的异常类型:
\ntry\n{\n string content = File.ReadAllText(@"C:\\temp\\missing.txt");\n}\ncatch (FileNotFoundException ex)\n{\n Console.WriteLine($"文件未找到:{ex.FileName}");\n}\ncatch (DirectoryNotFoundException ex)\n{\n Console.WriteLine($"目录未找到:{ex.Message}");\n}\ncatch (UnauthorizedAccessException ex)\n{\n Console.WriteLine($"访问被拒绝:{ex.Message}");\n}\ncatch (IOException ex)\n{\n Console.WriteLine($"IO错误:{ex.Message}");\n}\n使用 using 语句或 finally 块确保资源释放:
FileStream fs = null;\ntry\n{\n fs = new FileStream(@"C:\\temp\\data.txt", FileMode.Open);\n // 处理文件...\n}\nfinally\n{\n if (fs != null)\n fs.Dispose();\n}\n\n结论
\n掌握在C#中处理文件系统是开发可靠应用程序的关键。在本文中,我们涵盖了:
\n- \n
- 使用
File、FileInfo、Directory和DirectoryInfo进行基本操作 \n - 使用
FileStream、StreamReader和StreamWriter进行高效流处理 \n - 处理特定异常类型的最佳实践 \n
- 使用
using语句进行正确的资源管理 \n
实践建议:始终检查文件或目录是否存在(File.Exists、Directory.Exists),使用相对路径而非硬编码绝对路径,并考虑使用 Path.Combine 构建路径。祝您编码愉快!