在C#项目开发中,文件操作是非常常见的需求,但是直接使用System.IO命名空间下的原生类,往往需要重复处理路径校验、异常捕获、流资源释放等逻辑,不仅代码冗余,还容易因为疏忽导致bug。封装一个通用的文件操作类,可以把这些通用逻辑统一处理,让业务层的文件操作调用更简洁。

封装类的核心设计思路
设计文件操作封装类时,需要覆盖常用的文件操作场景,同时保证健壮性:
- 支持文件的创建、删除、移动、复制等基础操作
- 支持文本文件的读写、二进制文件的读写
- 自动处理路径合法性校验,避免非法路径导致的异常
- 确保流资源在使用后正确释放,避免内存泄漏
- 统一异常捕获,返回清晰的错误信息
完整封装类实例代码
以下是完整的C#文件操作封装类实现,包含常用功能:
using System;
using System.IO;
using System.Text;
namespace Common.Utils
{
/// <summary>
/// 文件操作封装类
/// </summary>
public class FileHelper
{
/// <summary>
/// 检查文件是否存在
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>存在返回true,否则返回false</returns>
public static bool Exists(string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
return false;
}
return File.Exists(filePath);
}
/// <summary>
/// 创建文件,如果文件已存在则覆盖
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="content">文件内容</param>
/// <param name="encoding">编码格式,默认UTF8</param>
public static void CreateFile(string filePath, string content, Encoding encoding = null)
{
CheckFilePath(filePath);
encoding = encoding ?? Encoding.UTF8;
string directory = Path.GetDirectoryName(filePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
File.WriteAllText(filePath, content, encoding);
}
/// <summary>
/// 读取文本文件内容
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="encoding">编码格式,默认UTF8</param>
/// <returns>文件内容字符串</returns>
public static string ReadTextFile(string filePath, Encoding encoding = null)
{
if (!Exists(filePath))
{
throw new FileNotFoundException("目标文件不存在", filePath);
}
encoding = encoding ?? Encoding.UTF8;
return File.ReadAllText(filePath, encoding);
}
/// <summary>
/// 追加内容到文本文件
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="content">追加的内容</param>
/// <param name="encoding">编码格式,默认UTF8</param>
public static void AppendText(string filePath, string content, Encoding encoding = null)
{
CheckFilePath(filePath);
encoding = encoding ?? Encoding.UTF8;
string directory = Path.GetDirectoryName(filePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
File.AppendAllText(filePath, content, encoding);
}
/// <summary>
/// 删除指定文件
/// </summary>
/// <param name="filePath">文件路径</param>
public static void DeleteFile(string filePath)
{
if (Exists(filePath))
{
File.Delete(filePath);
}
}
/// <summary>
/// 复制文件到目标路径
/// </summary>
/// <param name="sourcePath">源文件路径</param>
/// <param name="targetPath">目标文件路径</param>
/// <param name="overwrite">是否覆盖已存在的文件,默认true</param>
public static void CopyFile(string sourcePath, string targetPath, bool overwrite = true)
{
if (!Exists(sourcePath))
{
throw new FileNotFoundException("源文件不存在", sourcePath);
}
CheckFilePath(targetPath);
string targetDir = Path.GetDirectoryName(targetPath);
if (!Directory.Exists(targetDir))
{
Directory.CreateDirectory(targetDir);
}
File.Copy(sourcePath, targetPath, overwrite);
}
/// <summary>
/// 移动文件到目标路径
/// </summary>
/// <param name="sourcePath">源文件路径</param>
/// <param name="targetPath">目标文件路径</param>
public static void MoveFile(string sourcePath, string targetPath)
{
if (!Exists(sourcePath))
{
throw new FileNotFoundException("源文件不存在", sourcePath);
}
CheckFilePath(targetPath);
string targetDir = Path.GetDirectoryName(targetPath);
if (!Directory.Exists(targetDir))
{
Directory.CreateDirectory(targetDir);
}
// 如果目标文件已存在,先删除
if (Exists(targetPath))
{
File.Delete(targetPath);
}
File.Move(sourcePath, targetPath);
}
/// <summary>
/// 读取二进制文件为字节数组
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>字节数组</returns>
public static byte[] ReadBinaryFile(string filePath)
{
if (!Exists(filePath))
{
throw new FileNotFoundException("目标文件不存在", filePath);
}
return File.ReadAllBytes(filePath);
}
/// <summary>
/// 写入字节数组到文件
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="data">字节数组</param>
public static void WriteBinaryFile(string filePath, byte[] data)
{
CheckFilePath(filePath);
string directory = Path.GetDirectoryName(filePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
File.WriteAllBytes(filePath, data);
}
/// <summary>
/// 校验文件路径合法性
/// </summary>
/// <param name="filePath">文件路径</param>
private static void CheckFilePath(string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
throw new ArgumentNullException(nameof(filePath), "文件路径不能为空");
}
// 校验路径是否包含非法字符
char[] invalidChars = Path.GetInvalidPathChars();
if (filePath.IndexOfAny(invalidChars) != -1)
{
throw new ArgumentException("文件路径包含非法字符", nameof(filePath));
}
}
}
}封装类使用示例
在业务代码中调用封装类非常简单,以下是几个常见场景的调用示例:
// 检查文件是否存在 bool isExist = FileHelper.Exists(@"D:\test\test.txt"); // 创建文本文件并写入内容 FileHelper.CreateFile(@"D:\test\test.txt", "这是封装类写入的测试内容"); // 读取文本文件内容 string content = FileHelper.ReadTextFile(@"D:\test\test.txt"); Console.WriteLine(content); // 追加内容到文件 FileHelper.AppendText(@"D:\test\test.txt", "\n这是追加的第二行内容"); // 复制文件 FileHelper.CopyFile(@"D:\test\test.txt", @"D:\test\copy\test.txt"); // 读取二进制文件(比如图片) byte[] imgData = FileHelper.ReadBinaryFile(@"D:\test\image.jpg"); // 写入二进制文件 FileHelper.WriteBinaryFile(@"D:\test\new_image.jpg", imgData); // 删除文件 FileHelper.DeleteFile(@"D:\test\test.txt");
注意事项
使用这个封装类时,需要注意以下几点:
- 所有方法都做了基础的路径校验,但是如果传入的路径没有读写权限,还是会抛出权限相关的异常,建议在业务层额外捕获这类异常
- 大文件读写场景不建议使用
File.ReadAllText或者File.ReadAllBytes这类一次性读取的方法,可以自行扩展基于FileStream的分块读写方法 - 编码参数默认使用UTF8,如果操作的是其他编码的文件,调用时传入对应的编码即可
封装类的核心目的是减少重复代码,提升开发效率,开发者可以根据自己项目的实际需求,对现有方法进行扩展或者调整,比如增加文件大小限制、增加操作日志等功能。
C#文件操作封装类IO操作FileStream修改时间:2026-05-29 14:30:58