filehelper应封装高频易错操作,提供writealltext、readalltext、copy、getfiles四个核心方法,统一处理路径安全、编码、异常及异步i/o,不重复包装system.io全功能。

为什么直接用 System.IO 不够用
因为 File 和 Directory 静态类虽然功能全,但每做一件事都要手动判空、捕获异常、检查路径合法性。比如 File.Exists(path) 返回 false,你没法立刻知道是文件不存在,还是权限不足,或是路径含非法字符。真实业务里,一个“保存配置”操作常要:确保目录存在、创建缺失父目录、原子写入、失败时清理临时文件——这些逻辑反复出现,不封装就会散落在各处。
FileHelper 应该只暴露哪些核心方法
聚焦高频、易出错、有共性处理的场景,不是把 System.IO 全部重包一层。推荐这四个入口:
-
WriteAllText(string path, string content, Encoding? encoding = null):自动创建父目录,抛出带上下文的异常(如“无法创建目录 D:\a\b\c”) -
ReadAllText(string path, Encoding? encoding = null):统一处理FileNotFoundException和UnauthorizedAccessException,转为更明确的业务异常 -
Copy(string source, string dest, bool overwrite = false):内部调用File.Copy,但先校验源文件可读、目标目录可写,并支持取消令牌 -
GetFiles(string directory, string pattern = "*.*", SearchOption option = SearchOption.TopDirectoryOnly):返回IEnumerable<string></string>而非数组,避免大目录一次性加载内存
路径安全和编码问题怎么兜底
用户传进来的 path 很可能含 ..、空格、Unicode 控制符,或默认用系统编码读中文内容却在 Linux 上运行。必须在入口就拦截:
- 用
Path.GetFullPath(path)归一化路径,再用Path.IsPathRooted()+ 检查是否以Path.GetPathRoot()开头,防路径穿越 - 对所有
path参数做string.IsNullOrWhiteSpace()和Path.GetInvalidPathChars()扫描,发现非法字符立即抛ArgumentException -
ReadAllText/WriteAllText默认用Encoding.UTF8,不依赖Encoding.Default—— 后者在中文 Windows 是 GB2312,在 Docker 容器里可能是 ASCII
异步支持要不要加?加到什么程度
加,但只加真正阻塞 I/O 的方法,比如 ReadAllTextAsync 和 WriteAllTextAsync。别为了“看起来现代”而给 Exists 或 Delete 加 Async 后缀——它们底层是元数据查询,同步调用开销极小,强行异步反而增加调度成本。
关键点:
- 异步方法内部用
File.ReadAllTextAsync/File.WriteAllTextAsync,不自己开线程池 - 所有异步方法签名必须接受
CancellationToken,且在打开文件前就检查是否已取消 - 不要提供“同步转异步”的包装器(如
Task.Run(() => ReadAllText(...))),这是反模式
真正难处理的是长路径(>260 字符)和符号链接循环——这些得靠调用方自己控制输入,帮助类最多在文档里标红提醒,硬拦会破坏灵活性。









