在C#开发中,文件写入是数据持久化、日志记录、配置管理等场景的基础操作。System.IO命名空间提供了三种核心的文件写入方式——File静态类、StreamWriter类和FileStream类,它们分别适用于不同的业务场景,各有技术特点。本文将从应用场景、技术要点和代码示例三个维度进行系统讲解。
核心特点:File是静态类,提供了一系列"一步到位"的写入方法,内部自动完成打开文件、写入数据、关闭文件的全过程,开发者无需手动管理流的生命周期。
常用写入方法:WriteAllText(path, content, encoding)用于一次性覆盖写入整段文本;AppendAllText(path, content, encoding)用于在文件末尾追加文本,文件不存在时自动创建;WriteAllLines(path, string[], encoding)用于将字符串数组逐行写入文件;WriteAllBytes(path, byte[])用于以字节数组形式写入,适用于所有文件类型。
适用场景:适合小文件(通常小于1MB)的一次性写入操作,如配置文件生成、小型数据快照保存、简单的日志追加等。代码最为简洁,但会将全部内容一次性加载到内存中,不适合大文件场景。
代码示例:
using System.IO;
using System.Text;
string path = "output.txt";
// 覆盖写入
File.WriteAllText(path, "Hello World", Encoding.UTF8);
// 追加写入
File.AppendAllText(path, "\n追加的内容", Encoding.UTF8);
// 数组逐行写入
string[] lines = { "第一行", "第二行", "第三行" };
File.WriteAllLines(path, lines, Encoding.UTF8);核心特点:StreamWriter继承自TextWriter,专为字符级文本写入设计。它内部封装了FileStream,自动处理字符编码转换(默认UTF-8无BOM)、缓冲机制和行结束符标准化,是文本文件写入最常用的方案。
技术要点:StreamWriter默认启用4096字节缓冲区,写入操作先存入内存缓冲区,仅在缓冲区满、调用Flush()或Dispose()时才批量刷入磁盘,大幅减少磁盘I/O次数。构造函数的第二个参数设为true即可启用追加模式。在ASP.NET Core或WPF等场景中,应使用WriteAsync/WriteLineAsync异步方法避免阻塞线程。必须使用using语句包裹实例,确保异常时也能正确释放文件句柄并刷盘。
适用场景:适合需要逐行或分块写入文本的场景,如日志系统、CSV文件生成、大数据量文本导出等。相比File类,它在内存控制和写入灵活性上更具优势。
代码示例:
using System.IO;
using System.Text;
string path = "log.txt";
// 同步写入(追加模式,指定UTF-8编码)
using (StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8))
{
sw.WriteLine($"[{DateTime.Now}] 程序启动");
sw.WriteLine($"[{DateTime.Now}] 用户登录成功");
}
// 异步写入(适合UI线程或服务端高并发场景)
using (StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8))
{
await sw.WriteLineAsync("异步写入第一行");
await sw.WriteLineAsync("异步写入第二行");
}核心特点:FileStream是所有文件I/O操作的底层基石,直接操作字节流,提供对文件的完全控制能力,包括随机访问(Seek)、自定义缓冲区大小、文件共享模式、异步I/O等。
技术要点:FileStream操作的是原始字节(byte[]),写入文本时需手动通过Encoding.GetBytes()将字符串转为字节数组。通过FileMode(Create/Open/Append等)、FileAccess(Read/Write/ReadWrite)和FileShare参数可精确控制文件的打开方式。支持Seek方法实现文件指针跳转,适用于断点续传、大文件分段写入等场景。构造函数中useAsync: true参数可启用操作系统级异步I/O(IOCP),性能远超同步线程池模拟。
适用场景:适合二进制文件写入(图片、视频、加密数据)、大文件分块写入、需要随机访问的文件操作、以及需要精细控制缓冲区大小和文件共享权限的高性能场景。
代码示例:
using System.IO;
using System.Text;
string path = "data.bin";
// 分块写入大文件(控制内存占用)
const int bufferSize = 4096;
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
byte[] buffer = new byte[bufferSize];
for (int i = 0; i < 1000; i++)
{
// 模拟填充数据
buffer = Encoding.UTF8.GetBytes($"数据块 {i}\n");
fs.Write(buffer, 0, buffer.Length);
}
}
// 随机访问写入(跳转到指定位置)
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
{
fs.Seek(100, SeekOrigin.Begin); // 跳转到第100字节位置
byte[] data = Encoding.UTF8.GetBytes("覆盖写入");
fs.Write(data, 0, data.Length);
}![]()
三种文件写入方式各有定位:File静态类适合小文件的一次性快速写入,代码最简洁;StreamWriter是文本写入的标准方案,内置编码处理和缓冲机制,适合日志、CSV等逐行写入场景;FileStream提供最底层的字节级控制,适合二进制文件、大文件分块写入和需要随机访问的高性能场景。在实际开发中,应根据数据量大小、文件类型、性能要求和编码需求选择最合适的方案。无论使用哪种方式,都应遵循两个基本原则:一是始终使用using语句确保资源正确释放,二是显式指定编码(推荐UTF-8)以避免跨平台乱码问题。
声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com
通过手机号码查询近3个月总停机次数标签信息,统计近3个月内停机的次数。
通过手机号查询判断该号码实名用户年龄区间标签信息。
通过三网运营商手机号码和指定月份,查询号码近3个月话费消费区间标签详情及评分。
通过车架号或车牌号查询车辆是否为营运车辆
通过车架号查询车辆的如品牌名称、车系名称、车型、排量、排放标准、外形尺寸、轮胎规格、变速器类型、公告号、轴距等等详细信息