C# 文件输入与输出(File I/O)教程
本章节为全面详尽的 C# 文件输入与输出(File I/O)教程,涵盖基础到高级内容,包含实战案例与多种方法,适用于控制台程序、桌面应用、ASP.NET 等各种场景。
📚 目录
- 文件 I/O 基本概念
- 常用类介绍(
File,FileInfo,StreamReader,StreamWriter, 等) - 读取文件的方式(多种方式对比)
- 写入文件的方式(追加、覆盖等)
- 文件与目录操作(复制、删除、移动、创建)
- 二进制读写(
BinaryReader/BinaryWriter) - 异步文件 I/O(async/await)
- 异常处理与资源释放(
using) - 实战案例:日志写入器、文件合并工具、简易文本编辑器
- 参考链接
1. 文件 I/O 基本概念
文件 I/O(Input/Output)即文件的读取与写入,是通过 System.IO 命名空间下的类实现的,常见任务包括:
- 读取文件内容
- 写入/追加文件
- 检查文件是否存在
- 操作文件夹(复制、删除、移动)
2. 常用类介绍
| 类名 | 说明 |
|---|---|
File | 提供静态方法,用于创建、复制、删除、移动文件 |
FileInfo | 与 File 类功能类似,但为实例方法 |
StreamReader | 用于读取文本文件 |
StreamWriter | 用于写入文本文件 |
BinaryReader / BinaryWriter | 用于二进制读写 |
Path | 提供路径处理的静态方法 |
Directory / DirectoryInfo | 目录操作类 |
3. 文件读取的方式
✅ 方法 1:File.ReadAllText()
string content = File.ReadAllText("example.txt");
Console.WriteLine(content);
✅ 方法 2:逐行读取
foreach (string line in File.ReadLines("example.txt"))
{
Console.WriteLine(line);
}
✅ 方法 3:使用 StreamReader
using (StreamReader reader = new StreamReader("example.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
4. 文件写入的方式
✅ 覆盖写入:File.WriteAllText
File.WriteAllText("output.txt", "Hello, world!");
✅ 追加写入:File.AppendAllText
File.AppendAllText("output.txt", "追加内容\n");
✅ 使用 StreamWriter
using (StreamWriter writer = new StreamWriter("output.txt", append: true))
{
writer.WriteLine("追加一行文字");
}
5. 文件与目录操作
// 检查文件是否存在
if (File.Exists("example.txt")) { ... }
// 创建文件
File.Create("newfile.txt").Dispose(); // 注意释放文件句柄
// 删除文件
File.Delete("example.txt");
// 移动文件
File.Move("a.txt", "b.txt");
// 复制文件
File.Copy("source.txt", "copy.txt", overwrite: true);
📁 文件夹操作:
// 创建文件夹
Directory.CreateDirectory("data");
// 获取所有 txt 文件
var files = Directory.GetFiles("data", "*.txt");
6. 二进制读写
// 写入
using (BinaryWriter writer = new BinaryWriter(File.Open("data.bin", FileMode.Create)))
{
writer.Write(42);
writer.Write("Hello");
writer.Write(true);
}
// 读取
using (BinaryReader reader = new BinaryReader(File.Open("data.bin", FileMode.Open)))
{
int number = reader.ReadInt32();
string text = reader.ReadString();
bool flag = reader.ReadBoolean();
}
7. 异步文件读写(C# 5+)
string content = await File.ReadAllTextAsync("example.txt");
await File.WriteAllTextAsync("output.txt", content);
8. 异常处理与资源释放
永远使用 using 或 try-finally,确保资源释放:
try
{
using StreamReader sr = new StreamReader("data.txt");
Console.WriteLine(await sr.ReadToEndAsync());
}
catch (IOException ex)
{
Console.WriteLine($"文件错误:{ex.Message}");
}
9. 实战案例
📝 示例:日志记录器
public static class Logger
{
private static readonly string logPath = "app.log";
public static void Log(string message)
{
string logLine = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}";
File.AppendAllText(logPath, logLine + Environment.NewLine);
}
}
📂 示例:合并多个文本文件
string[] files = Directory.GetFiles("texts", "*.txt");
using (StreamWriter writer = new StreamWriter("merged.txt"))
{
foreach (var file in files)
{
string content = File.ReadAllText(file);
writer.WriteLine(content);
}
}
🛠️ 示例:文件大小检测器(显示文件大小 MB)
string path = "video.mp4";
if (File.Exists(path))
{
long size = new FileInfo(path).Length;
Console.WriteLine($"文件大小:{size / (1024 * 1024.0):F2} MB");
}
10. 关于WPF / WinForms 中的文件上传与下载实现
🔹 WPF / WinForms 文件选择器(上传)
使用 OpenFileDialog(需要引用 Microsoft.Win32 或 System.Windows.Forms):
✅ 示例 1:WPF 文件选择(上传)
using Microsoft.Win32;
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
if (openFileDialog.ShowDialog() == true)
{
string filePath = openFileDialog.FileName;
string content = File.ReadAllText(filePath);
MessageBox.Show(content);
}
✅ 示例 2:WinForms 文件选择器(上传)
using System.Windows.Forms;
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
string filePath = dialog.FileName;
string content = File.ReadAllText(filePath);
MessageBox.Show(content);
}
🔽 WPF / WinForms 文件下载(保存为)
使用 SaveFileDialog 保存内容到指定路径:
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Text file (*.txt)|*.txt";
if (saveFileDialog.ShowDialog() == true)
{
File.WriteAllText(saveFileDialog.FileName, "这是要保存的内容");
}
11. 关于ASP.NET Core 中处理文件上传(IFormFile)
ASP.NET Core 使用 IFormFile 接口处理前端上传的文件,支持单文件与多文件上传。
✅ 1. 创建文件上传接口(Controller)
[HttpPost("upload")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("文件为空");
var filePath = Path.Combine("Uploads", file.FileName);
// 确保上传目录存在
Directory.CreateDirectory("Uploads");
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return Ok(new { status = "成功", path = filePath });
}
✅ 2. Razor / HTML 上传页面
<form method="post" enctype="multipart/form-data" action="/upload">
<input type="file" name="file" />
<input type="submit" value="上传文件" />
</form>
✅ 3. 处理多个文件上传
[HttpPost("multi-upload")]
public async Task<IActionResult> UploadFiles(List<IFormFile> files)
{
foreach (var file in files)
{
var path = Path.Combine("Uploads", file.FileName);
using var stream = new FileStream(path, FileMode.Create);
await file.CopyToAsync(stream);
}
return Ok("文件上传成功");
}
HTML:
<form method="post" enctype="multipart/form-data" action="/multi-upload">
<input type="file" name="files" multiple />
<input type="submit" value="上传多个文件" />
</form>
🔽 ASP.NET Core 文件下载接口
[HttpGet("download/{filename}")]
public IActionResult DownloadFile(string filename)
{
var filePath = Path.Combine("Uploads", filename);
if (!System.IO.File.Exists(filePath))
return NotFound();
var contentType = "application/octet-stream";
return PhysicalFile(filePath, contentType, filename);
}
📎 访问链接示例:https://localhost:5001/download/sample.txt
🔐 安全建议
- 使用
Path.GetFileName避免路径穿越攻击 - 检查上传文件类型(MIME 类型与后缀)
- 限制文件大小(通过
RequestSizeLimit或全局设置) - 禁止执行上传目录下的文件(设置权限)
📚 参考链接
- 📘 ASP.NET Core – 上传文件文档
- 📘 WPF OpenFileDialog 使用
- 📘 SaveFileDialog 官方文档
- 📘 Microsoft Docs – System.IO
- 📘 File 类文档
- 📘 StreamReader 类文档
- 📘 C# 文件操作指南
更多详细内容,请关注其他相关文章!