文件操作
File 静态类
File 类提供文件操作的静态方法,适合一次性读写或简单操作。常用方法包括 ReadAllText、WriteAllText、AppendAllText、Exists、Copy、Move、Delete 和 ReadAllLines。
示例
CSHARP
using System;
using System.IO;
string path = "test.txt";
File.WriteAllText(path, "Hello, World!");
string content = File.ReadAllText(path);
Console.WriteLine(content);
File.AppendAllText(path, "\nAppended line.");
string[] lines = File.ReadAllLines(path);
foreach (string line in lines)
{
Console.WriteLine($"Line: {line}");
}
Console.WriteLine($"Exists: {File.Exists(path)}");
File.Copy(path, "copy.txt", overwrite: true);
File.Move("copy.txt", "moved.txt");
File.Delete("moved.txt");
File.Delete(path);
TEXT
Hello, World!
Line: Hello, World!
Line: Appended line.
Exists: True
Directory 静态类
Directory 类提供目录操作的静态方法,包括创建、删除、判断存在以及获取子文件和子目录列表。
示例
CSHARP
using System;
using System.IO;
string dir = "MyFolder";
Directory.CreateDirectory(dir);
Console.WriteLine($"Exists: {Directory.Exists(dir)}");
File.WriteAllText(Path.Combine(dir, "a.txt"), "aaa");
File.WriteAllText(Path.Combine(dir, "b.txt"), "bbb");
Directory.CreateDirectory(Path.Combine(dir, "SubDir"));
string[] files = Directory.GetFiles(dir);
Console.WriteLine("Files:");
foreach (string f in files)
{
Console.WriteLine($" {Path.GetFileName(f)}");
}
string[] dirs = Directory.GetDirectories(dir);
Console.WriteLine("Dirs:");
foreach (string d in dirs)
{
Console.WriteLine($" {Path.GetFileName(d)}");
}
Directory.Delete(dir, recursive: true);
TEXT
Exists: True
Files:
a.txt
b.txt
Dirs:
SubDir
FileInfo 与 DirectoryInfo 类
FileInfo 和 DirectoryInfo 是实例类,适合对同一文件或目录执行多次操作,避免重复路径校验,性能更优。
示例
CSHARP
using System;
using System.IO;
FileInfo fi = new FileInfo("demo.txt");
fi.WriteAllText("File info demo");
Console.WriteLine($"Name: {fi.Name}");
Console.WriteLine($"Length: {fi.Length}");
Console.WriteLine($"Extension: {fi.Extension}");
Console.WriteLine($"FullName: {fi.FullName}");
fi.Delete();
DirectoryInfo di = new DirectoryInfo("DemoDir");
di.Create();
Console.WriteLine($"Dir exists: {di.Exists}");
di.CreateSubdirectory("Child");
foreach (DirectoryInfo child in di.GetDirectories())
{
Console.WriteLine($"Sub: {child.Name}");
}
di.Delete(recursive: true);
TEXT
Name: demo.txt
Length: 14
Extension: .txt
FullName: ...\demo.txt
Dir exists: True
Sub: Child
Stream 抽象类与 FileStream
Stream 是所有流的抽象基类,提供 Read、Write、Seek 等方法。FileStream 是其派生类,以字节为单位进行低层读写。
示例
CSHARP
using System;
using System.IO;
using System.Text;
string filePath = "data.bin";
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
byte[] data = Encoding.UTF8.GetBytes("FileStream demo");
fs.Write(data, 0, data.Length);
}
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
Console.WriteLine(Encoding.UTF8.GetString(buffer));
}
File.Delete(filePath);
TEXT
FileStream demo
StreamReader 与 StreamWriter
StreamReader 和 StreamWriter 是面向文本的读写器,封装了编码处理,比 FileStream 更易用。StreamReader 按 ReadLine 读取,StreamWriter 按 WriteLine 写入。
示例
CSHARP
using System;
using System.IO;
string path = "text.txt";
using (StreamWriter writer = new StreamWriter(path))
{
writer.WriteLine("First line");
writer.WriteLine("Second line");
writer.Write("No newline here ");
writer.Write("appended.");
}
using (StreamReader reader = new StreamReader(path))
{
string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
File.Delete(path);
TEXT
First line
Second line
No newline here appended.
BinaryReader 与 BinaryWriter
BinaryReader 和 BinaryWriter 用于读写二进制数据,支持各种基元类型(int、double、string 等),适合处理非文本格式。
示例
CSHARP
using System;
using System.IO;
string path = "binary.dat";
using (BinaryWriter bw = new BinaryWriter(File.Open(path, FileMode.Create)))
{
bw.Write(42);
bw.Write(3.14);
bw.Write("hello");
}
using (BinaryReader br = new BinaryReader(File.Open(path, FileMode.Open)))
{
int num = br.ReadInt32();
double d = br.ReadDouble();
string s = br.ReadString();
Console.WriteLine($"Int: {num}, Double: {d}, String: {s}");
}
File.Delete(path);
TEXT
Int: 42, Double: 3.14, String: hello
Path 辅助类
Path 类提供路径操作的静态方法,跨平台处理路径分隔符,避免手动拼接字符串出错。常用方法有 Combine、GetExtension、GetFileName、GetDirectoryName 和 GetTempPath。
示例
CSHARP
using System;
using System.IO;
string fullPath = Path.Combine("folder", "sub", "file.txt");
Console.WriteLine($"Combine: {fullPath}");
Console.WriteLine($"Extension: {Path.GetExtension(fullPath)}");
Console.WriteLine($"FileName: {Path.GetFileName(fullPath)}");
Console.WriteLine($"FileNameNoExt: {Path.GetFileNameWithoutExtension(fullPath)}");
Console.WriteLine($"DirectoryName: {Path.GetDirectoryName(fullPath)}");
Console.WriteLine($"TempPath: {Path.GetTempPath()}");
TEXT
Combine: folder\sub\file.txt
Extension: .txt
FileName: file.txt
FileNameNoExt: file
DirectoryName: folder\sub
TempPath: ...\Temp\
using 语句与 IDisposable
文件、流等资源需要及时释放。using 语句确保即使发生异常也能调用 Dispose。C# 8+ 支持 using var 声明式写法。所有需要清理的资源类都实现 IDisposable 接口。
示例
CSHARP
using System;
using System.IO;
string path = "using_demo.txt";
using (StreamWriter sw = new StreamWriter(path))
{
sw.WriteLine("Block using");
}
using StreamReader sr = new StreamReader(path);
Console.WriteLine(sr.ReadLine());
File.Delete(path);
Console.WriteLine(typeof(Stream).GetInterface("IDisposable") != null);
TEXT
Block using
True
❓ 常见问题
Q File 和 FileInfo 该选哪个?
A 单次操作用 File 静态方法更简洁;对同一文件多次操作用 FileInfo 性能更好。
Q FileStream 和 StreamReader 有什么区别?
A FileStream 以字节读写,StreamReader 以文本读写并自动处理编码,推荐文本操作用 StreamReader。
Q using 语句中发生异常会释放资源吗?
A 会,using 编译为 try/finally,即使异常也调用 Dispose。
Q 为什么不应该用字符串拼接路径?
A 不同操作系统路径分隔符不同,用 Path.Combine 可跨平台安全拼接。
📖 小节
- File 静态类适合一次性文件操作
- Directory 静态类管理目录创建、删除与遍历
- FileInfo/DirectoryInfo 实例类适合多次操作同一目标
- Stream 是流抽象基类,FileStream 提供字节级读写
- StreamReader/StreamWriter 封装编码,简化文本读写
- BinaryReader/BinaryWriter 处理二进制基元类型数据
- Path 类安全处理跨平台路径操作
- using 语句确保 IDisposable 资源及时释放
📝 作业
- 编写程序,用 File.WriteAllText 写入一首诗,再用 File.ReadAllText 读取并输出
- 使用 Directory.CreateDirectory 创建多层目录,遍历输出其子目录和文件
- 用 StreamWriter 写入 5 行日志,再用 StreamReader 逐行读取并打印行号
- 使用 BinaryWriter 写入一组 int 值,用 BinaryReader 读回并求和
- 用 Path.Combine 拼接路径,分别输出文件名、扩展名和目录名



