csharp:第十一章文件io
目录
第十一章 文件IO
11.1 System.IO命名空间
主要类
| 类 | 用途 |
| —- | —— |
| File | 文件创建、复制、删除、移动等 |
| FileInfo | 文件详细信息和操作 |
| Directory | 目录操作 |
| DirectoryInfo | 目录详细信息和操作 |
| Path | 路径处理 |
| Stream | 字节流的抽象基类 |
| FileStream | 文件流 |
| MemoryStream | 内存流 |
| StreamReader | 字符流读取 |
| StreamWriter | 字符流写入 |
| BinaryReader | 二进制读取 |
| BinaryWriter | 二进制写入 |
11.2 文件操作
File类
using System.IO; // 检查文件是否存在 bool exists = File.Exists(@"C:\test.txt"); // 创建文件 File.Create(@"C:\newfile.txt").Close(); // 写入文本 File.WriteAllText(@"C:\test.txt", "Hello World"); File.WriteAllLines(@"C:\lines.txt", new[] { "Line1", "Line2", "Line3" }); File.AppendAllText(@"C:\test.txt", "\nAppended text"); // 读取文本 string content = File.ReadAllText(@"C:\test.txt"); string[] lines = File.ReadAllLines(@"C:\lines.txt"); // 复制、移动、删除 File.Copy(@"C:\source.txt", @"C:\dest.txt", overwrite: true); File.Move(@"C:\old.txt", @"C:\new.txt"); File.Delete(@"C:\delete.txt"); // 文件属性 var attributes = File.GetAttributes(@"C:\test.txt"); File.SetAttributes(@"C:\test.txt", FileAttributes.Hidden); // 时间信息 DateTime creationTime = File.GetCreationTime(@"C:\test.txt"); DateTime lastWrite = File.GetLastWriteTime(@"C:\test.txt"); DateTime lastAccess = File.GetLastAccessTime(@"C:\test.txt");
FileInfo类
var fileInfo = new FileInfo(@"C:\test.txt"); if (fileInfo.Exists) { Console.WriteLine($"文件名: {fileInfo.Name}"); Console.WriteLine($"完整路径: {fileInfo.FullName}"); Console.WriteLine($"大小: {fileInfo.Length} bytes"); Console.WriteLine($"创建时间: {fileInfo.CreationTime}"); Console.WriteLine($"修改时间: {fileInfo.LastWriteTime}"); Console.WriteLine($"扩展名: {fileInfo.Extension}"); Console.WriteLine($"目录: {fileInfo.DirectoryName}"); } // 操作方法 fileInfo.CopyTo(@"C:\backup.txt", overwrite: true); fileInfo.MoveTo(@"C:\newlocation.txt"); fileInfo.Delete();
11.3 目录操作
Directory类
// 创建目录 Directory.CreateDirectory(@"C:\NewFolder\SubFolder"); // 检查存在 bool exists = Directory.Exists(@"C:\TestFolder"); // 删除目录 Directory.Delete(@"C:\EmptyFolder"); // 空目录 Directory.Delete(@"C:\Folder", recursive: true); // 递归删除 // 获取文件 string[] files = Directory.GetFiles(@"C:\TestFolder"); string[] txtFiles = Directory.GetFiles(@"C:\TestFolder", "*.txt"); string[] allFiles = Directory.GetFiles(@"C:\TestFolder", "*.*", SearchOption.AllDirectories); // 获取子目录 string[] subDirs = Directory.GetDirectories(@"C:\TestFolder"); // 获取所有内容 string[] entries = Directory.GetFileSystemEntries(@"C:\TestFolder"); // 目录信息 DateTime creation = Directory.GetCreationTime(@"C:\TestFolder"); string parent = Directory.GetParent(@"C:\TestFolder\Sub").FullName; string root = Directory.GetDirectoryRoot(@"C:\TestFolder");
DirectoryInfo类
var dirInfo = new DirectoryInfo(@"C:\TestFolder"); if (dirInfo.Exists) { Console.WriteLine($"目录名: {dirInfo.Name}"); Console.WriteLine($"完整路径: {dirInfo.FullName}"); Console.WriteLine($"父目录: {dirInfo.Parent?.Name}"); Console.WriteLine($"根目录: {dirInfo.Root.Name}"); Console.WriteLine($"创建时间: {dirInfo.CreationTime}"); } // 获取文件和目录 FileInfo[] files = dirInfo.GetFiles(); FileInfo[] txtFiles = dirInfo.GetFiles("*.txt"); DirectoryInfo[] subDirs = dirInfo.GetDirectories(); // 递归获取 FileInfo[] allFiles = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
11.4 路径操作
using System.IO; // 组合路径 string path1 = Path.Combine(@"C:\Folder", "file.txt"); // C:\Folder\file.txt string path2 = Path.Combine(@"C:\Folder", "SubFolder", "file.txt"); // 获取路径各部分 string fileName = Path.GetFileName(@"C:\Folder\file.txt"); // file.txt string fileNameNoExt = Path.GetFileNameWithoutExtension(@"C:\Folder\file.txt"); // file string extension = Path.GetExtension(@"C:\Folder\file.txt"); // .txt string directory = Path.GetDirectoryName(@"C:\Folder\file.txt"); // C:\Folder string fullPath = Path.GetFullPath("file.txt"); // 完整路径 string root = Path.GetPathRoot(@"C:\Folder\file.txt"); // C:\ // 修改路径 string changeExt = Path.ChangeExtension(@"C:\file.txt", ".doc"); // C:\file.doc // 临时路径 string tempFile = Path.GetTempFileName(); // 创建临时文件 string tempPath = Path.GetTempPath(); // 临时目录 string randomFile = Path.GetRandomFileName(); // 随机文件名 // 路径特征检查 bool isRooted = Path.IsPathRooted(@"C:\file.txt"); // true bool isRooted2 = Path.IsPathRooted("file.txt"); // false // 跨平台路径 string altPath = Path.Combine("folder", "subfolder", "file.txt"); // Windows: folder\subfolder\file.txt // Linux/macOS: folder/subfolder/file.txt
11.5 流(Stream)
Stream基础
// 文件流 using (FileStream fs = new FileStream(@"C:\data.bin", FileMode.OpenOrCreate)) { // 写入数据 byte[] data = Encoding.UTF8.GetBytes("Hello World"); fs.Write(data, 0, data.Length); // 读取数据 fs.Position = 0; byte[] buffer = new byte[fs.Length]; int bytesRead = fs.Read(buffer, 0, buffer.Length); string text = Encoding.UTF8.GetString(buffer); } // FileMode枚举 // Create: 创建新文件,存在则覆盖 // CreateNew: 创建新文件,存在则异常 // Open: 打开现有文件 // OpenOrCreate: 打开或创建 // Append: 追加,若存在则定位到末尾 // Truncate: 打开并截断为零长度
内存流
using (MemoryStream ms = new MemoryStream()) { // 写入 byte[] data = Encoding.UTF8.GetBytes("Memory stream test"); ms.Write(data, 0, data.Length); // 获取字节数组 byte[] allBytes = ms.ToArray(); // 读取 ms.Position = 0; using (StreamReader reader = new StreamReader(ms)) { string text = reader.ReadToEnd(); Console.WriteLine(text); } } // 从字节数组创建 byte[] existingData = Encoding.UTF8.GetBytes("Existing data"); using (MemoryStream ms = new MemoryStream(existingData)) { // 读取existingData }
11.6 读写器
StreamReader和StreamWriter
// 写入文本 using (StreamWriter writer = new StreamWriter(@"C:\output.txt")) { writer.WriteLine("第一行"); writer.WriteLine("第二行"); writer.Write("不换行"); writer.Write("继续"); } // 追加模式 using (StreamWriter writer = new StreamWriter(@"C:\output.txt", append: true)) { writer.WriteLine("追加的内容"); } // 指定编码 using (StreamWriter writer = new StreamWriter(@"C:\output.txt", append: false, encoding: Encoding.UTF8)) { writer.WriteLine("UTF-8编码"); } // 读取文本 using (StreamReader reader = new StreamReader(@"C:\input.txt")) { // 读取所有内容 string allText = reader.ReadToEnd(); // 读取一行 reader.BaseStream.Position = 0; string line = reader.ReadLine(); // 逐行读取 reader.BaseStream.Position = 0; string currentLine; while ((currentLine = reader.ReadLine()) != null) { Console.WriteLine(currentLine); } } // 异步读写 using (StreamWriter writer = new StreamWriter(@"C:\async.txt")) { await writer.WriteLineAsync("异步写入"); } using (StreamReader reader = new StreamReader(@"C:\async.txt")) { string text = await reader.ReadToEndAsync(); }
BinaryReader和BinaryWriter
// 二进制写入 using (FileStream fs = new FileStream(@"C:\data.bin", FileMode.Create)) using (BinaryWriter writer = new BinaryWriter(fs)) { writer.Write(123); // int writer.Write(45.67); // double writer.Write("Hello"); // string writer.Write(true); // bool writer.Write(new byte[] { 1, 2, 3 }); // byte[] } // 二进制读取 using (FileStream fs = new FileStream(@"C:\data.bin", FileMode.Open)) using (BinaryReader reader = new BinaryReader(fs)) { int num = reader.ReadInt32(); double dbl = reader.ReadDouble(); string str = reader.ReadString(); bool flag = reader.ReadBoolean(); byte[] bytes = reader.ReadBytes(3); Console.WriteLine($"{num}, {dbl}, {str}, {flag}"); }
11.7 序列化
JSON序列化(System.Text.Json)
using System.Text.Json; public class Person { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } } // 序列化 Person person = new Person { Name = "张三", Age = 30, Email = "zhangsan@example.com" }; string json = JsonSerializer.Serialize(person); File.WriteAllText(@"C:\person.json", json); // 美化输出 string prettyJson = JsonSerializer.Serialize(person, new JsonSerializerOptions { WriteIndented = true }); // 反序列化 string jsonContent = File.ReadAllText(@"C:\person.json"); Person deserialized = JsonSerializer.Deserialize<Person>(jsonContent); // 集合序列化 List<Person> people = new List<Person> { person, new Person { Name = "李四", Age = 25 } }; string listJson = JsonSerializer.Serialize(people); var peopleList = JsonSerializer.Deserialize<List<Person>>(listJson);
XML序列化
using System.Xml.Serialization; [Serializable] public class Employee { public string Name { get; set; } public int Id { get; set; } public decimal Salary { get; set; } [XmlIgnore] public string Password { get; set; } // 不序列化 } // XML序列化 Employee emp = new Employee { Name = "王五", Id = 1001, Salary = 5000 }; XmlSerializer xmlSerializer = new XmlSerializer(typeof(Employee)); using (FileStream fs = new FileStream(@"C:\employee.xml", FileMode.Create)) { xmlSerializer.Serialize(fs, emp); } // XML反序列化 using (FileStream fs = new FileStream(@"C:\employee.xml", FileMode.Open)) { Employee deserialized = (Employee)xmlSerializer.Deserialize(fs); Console.WriteLine(deserialized.Name); }
11.8 异步文件操作
// 异步读写文件 public async Task FileOperationsAsync() { // 异步写入 await File.WriteAllTextAsync(@"C:\async.txt", "异步内容"); // 异步读取 string content = await File.ReadAllTextAsync(@"C:\async.txt"); // 异步流操作 using (FileStream fs = new FileStream(@"C:\largefile.txt", FileMode.Open)) using (StreamReader reader = new StreamReader(fs)) { string line; while ((line = await reader.ReadLineAsync()) != null) { Console.WriteLine(line); } } } // 异步复制大文件 public async Task CopyLargeFileAsync(string source, string destination) { using (FileStream sourceStream = new FileStream(source, FileMode.Open)) using (FileStream destStream = new FileStream(destination, FileMode.Create)) { await sourceStream.CopyToAsync(destStream); } }
练习题
基础练习
1. 文件复制器:编写程序将指定目录中的所有.txt文件复制到另一个目录。
2. 日志类:实现简单的文件日志类,支持:
- 按日期创建日志文件
- 日志级别(Info、Warning、Error)
- 文件大小限制,超过则创建新文件
3. 配置管理器:实现JSON配置文件管理器:
- 读取配置
- 保存配置
- 配置变更通知
进阶练习
4. 文件监视器:使用FileSystemWatcher监视目录:
- 检测文件创建、修改、删除、重命名
- 记录所有变更到日志
- 支持过滤特定文件类型
5. 文件分割器:实现大文件分割和合并:
- 按指定大小分割文件
- 合并分割后的文件
- 验证完整性
6. 文件加密器:实现简单的文件加密:
- 使用AES算法
- 加密文件内容
- 解密文件内容
挑战练习
7. 虚拟文件系统:在内存中实现简单的文件系统:
- 支持目录和文件
- 支持基本的CRUD操作
- 可导出到真实文件系统
8. 文件同步工具:实现文件夹同步工具:
- 单向/双向同步
- 冲突检测和解决
- 增量同步
- 删除保护
本章小结
本章学习了C#文件IO操作:
- File和FileInfo类
- Directory和DirectoryInfo类
- Path类的路径操作
- Stream的概念和使用
- 文本和二进制读写器
- JSON和XML序列化
- 异步文件操作
掌握文件IO是开发实际应用程序的基础技能。
csharp/第十一章文件io.txt · 最后更改: 由 127.0.0.1
