1. C# 文件操作基础概念
1.1 内存与持久化存储的区别
在程序运行时,我们操作的数据(变量、数组、对象等)都存储在内存中。内存的特点是临时性 - 程序结束或系统崩溃时,内存中的数据就会丢失。与之相对的,硬盘、U盘等存储设备提供的是持久化存储,数据可以长期保存。
文件就是操作系统对持久化数据的基本管理单元。你可以把文件理解为:
一组相关数据的集合,以特定格式存储在磁盘上,可以长期保存和使用。
常见的文件类型包括:
- 文本文件(.txt, .csv)
- 图片文件(.jpg, .png)
- 音频文件(.mp3, .wav)
- 可执行文件(.exe, .dll)
1.2 目录与路径系统
随着文件数量增加,有效的组织管理变得至关重要。目录(文件夹)就是用来对文件进行分类管理的结构。
路径则是定位文件的"地址",通常格式为:
上级目录\子目录\文件名.扩展名
例如:
D:\Projects\CSharpDemo\Program.cs
路径分为两种类型:
- 绝对路径:从根目录开始的完整路径
- 相对路径:相对于当前工作目录的路径
在实际开发中,我们更推荐使用相对路径,因为绝对路径在不同机器上可能无法正常工作。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. System.IO 命名空间概览
2.1 核心功能组件
C# 中的文件操作主要依赖于 System.IO 命名空间,它提供了三大类功能:
-
目录操作:
- 创建/删除目录
- 遍历目录内容
- 检查目录状态
-
文件操作:
- 创建/删除文件
- 复制/移动文件
- 获取文件属性
-
文件内容读写:
- 文本读写
- 二进制数据读写
- 流式操作
2.2 Path 类的实用功能
Path 是一个静态工具类,专门用于处理路径字符串操作。它的主要特点包括:
- 跨平台兼容(自动处理Windows/Linux/macOS的路径差异)
- 提供安全的路径拼接和解析方法
- 不实际访问文件系统,仅操作字符串
常用方法示例:
csharp复制// 安全拼接路径
string fullPath = Path.Combine("C:", "Folder", "Subfolder", "file.txt");
// 解析路径组件
string dir = Path.GetDirectoryName(fullPath); // 获取目录部分
string fileName = Path.GetFileName(fullPath); // 获取文件名
string ext = Path.GetExtension(fullPath); // 获取扩展名
注意:Path类的方法不会验证路径是否真实存在,它们只是处理字符串。
3. 文件基础操作实战
3.1 文件存在性检查
在进行任何文件操作前,通常需要先检查文件是否存在:
csharp复制string filePath = @"C:\example\test.txt";
if(File.Exists(filePath))
{
Console.WriteLine("文件存在");
}
else
{
Console.WriteLine("文件不存在");
}
3.2 创建与删除文件
创建新文件有多种方式:
csharp复制// 方法1:创建空文件
File.Create(@"C:\example\newfile.txt").Close();
// 方法2:创建并写入内容
File.WriteAllText(@"C:\example\newfile.txt", "初始内容");
删除文件很简单:
csharp复制File.Delete(@"C:\example\oldfile.txt");
3.3 文件复制与移动
复制文件(可选择是否覆盖目标文件):
csharp复制// 不覆盖已存在文件
File.Copy(sourcePath, destPath);
// 强制覆盖
File.Copy(sourcePath, destPath, true);
移动/重命名文件:
csharp复制// 移动文件到新位置
File.Move(@"C:\old\location.txt", @"D:\new\location.txt");
// 重命名文件
File.Move(@"C:\example\oldname.txt", @"C:\example\newname.txt");
4. 文件内容读写技术
4.1 简单读写方法
对于小型文件,可以使用这些便捷方法:
csharp复制// 写入全部文本
File.WriteAllText("test.txt", "Hello World!");
// 追加文本
File.AppendAllText("test.txt", "\n追加内容");
// 读取全部文本
string content = File.ReadAllText("test.txt");
// 按行读取
string[] lines = File.ReadAllLines("test.txt");
4.2 流式读写(推荐方式)
对于大型文件或需要精细控制的场景,应该使用流式操作:
csharp复制// 写入文件
using (FileStream fs = new FileStream("data.bin", FileMode.Create))
{
byte[] data = Encoding.UTF8.GetBytes("流式写入示例");
fs.Write(data, 0, data.Length);
}
// 读取文件
using (FileStream fs = new FileStream("data.bin", FileMode.Open))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
string content = Encoding.UTF8.GetString(buffer);
}
4.3 文本编码处理
正确处理文本编码至关重要:
csharp复制// 指定编码写入
File.WriteAllText("utf8.txt", "UTF-8示例", Encoding.UTF8);
// 指定编码读取
string content = File.ReadAllText("gb2312.txt", Encoding.GetEncoding("GB2312"));
常见编码:
- UTF-8(推荐,国际标准)
- GB2312/GBK(中文编码)
- ASCII(基本英文字符)
- Unicode(UTF-16)
5. 目录操作实战
5.1 基本目录操作
csharp复制// 创建目录(自动创建父目录)
Directory.CreateDirectory(@"C:\Parent\Child");
// 删除目录(递归删除)
Directory.Delete(@"C:\Parent", true);
// 移动/重命名目录
Directory.Move(@"C:\OldDir", @"D:\NewDir");
5.2 目录遍历
获取目录内容:
csharp复制// 获取所有文件
string[] files = Directory.GetFiles(@"C:\example");
// 获取特定类型文件
string[] pdfFiles = Directory.GetFiles(@"C:\example", "*.pdf");
// 递归获取所有子目录文件
string[] allFiles = Directory.GetFiles(@"C:\example", "*", SearchOption.AllDirectories);
// 获取子目录
string[] subDirs = Directory.GetDirectories(@"C:\example");
5.3 目录信息获取
csharp复制// 获取当前工作目录
string currentDir = Directory.GetCurrentDirectory();
// 获取父目录
DirectoryInfo parent = Directory.GetParent(currentDir);
6. 高级流操作技术
6.1 FileStream 详解
FileStream 提供低级别的文件访问控制:
csharp复制// 高级FileStream用法
using (FileStream fs = new FileStream("data.bin",
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.Read,
4096,
FileOptions.Asynchronous))
{
// 随机访问
fs.Seek(100, SeekOrigin.Begin);
// 读写操作
byte[] buffer = new byte[1024];
int bytesRead = fs.Read(buffer, 0, buffer.Length);
// 写入数据
fs.Write(buffer, 0, bytesRead);
// 刷新缓冲区
fs.Flush();
}
6.2 缓冲流优化
BufferedStream 可以显著提升I/O性能:
csharp复制// 使用缓冲流
using (FileStream fs = new FileStream("largefile.dat", FileMode.Open))
using (BufferedStream bs = new BufferedStream(fs, 65536)) // 64KB缓冲区
{
// 读写操作会利用缓冲区
byte[] data = new byte[1024];
bs.Read(data, 0, data.Length);
}
6.3 文本流封装
StreamReader/StreamWriter 简化文本处理:
csharp复制// 写入文本
using (StreamWriter writer = new StreamWriter("log.txt", true, Encoding.UTF8))
{
writer.WriteLine($"{DateTime.Now}: 系统启动");
}
// 读取文本
using (StreamReader reader = new StreamReader("log.txt", Encoding.UTF8))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
Console.WriteLine(line);
}
}
7. 资源管理与异常处理
7.1 使用using语句
确保非托管资源及时释放:
csharp复制// 正确做法
using (FileStream fs = new FileStream("file.txt", FileMode.Open))
{
// 使用文件流
} // 自动调用Dis
