System.Formats.Tar 是只读解析器,仅支持解包,不提供 TarWriter 等写入 API;创建 TAR 包需用 SharpCompress,其支持 ArchiveType.Tar、路径统一用 /、可设时间戳,并能生成 .tar 或 .tar.gz。

System.Formats.Tar 是只读的,不能用来创建 TAR 包
直接说结论:System.Formats.Tar 是 .NET 6+ 引入的**只读解析器**,它没有 TarWriter 或任何写入 API。你调用 TarReader 可以解包,但试图用它打包会发现根本不存在对应类型。
常见错误现象是查文档看到命名空间里有 Tar 就以为支持双向操作,结果编译失败或 IDE 提示 TarWriter 未定义。
- 该命名空间下只有
TarReader、TarEntry、TarEntryHeader等读取相关类型 - 没有
TarWriter、Create、AddEntry等方法 - 官方文档明确标注为 “read-only tar archive support”
创建 TAR 包得用第三方库:SharpCompress 最常用
SharpCompress 是目前 C# 生态中对 TAR 支持最完整、文档最清晰的开源库,支持纯托管写入(无需外部依赖),且能处理 GNU/POSIX 格式、长路径、硬链接等真实场景需求。
安装方式:
dotnet add package SharpCompress
关键点:
- 必须用
ArchiveType.Tar,不是ArchiveType.Zip - 写入需通过
TarWriter(来自SharpCompress.Writers),不是System.Formats.Tar - 路径分隔符统一用
/(TAR 规范要求),即使在 Windows 上也要转换\→/ - 文件时间戳默认用
DateTime.Now,如需固定时间(比如构建可重现性),要手动设置entry.LastModifiedTime
一个最小可行的 TAR 创建示例
以下代码把两个文件打成 archive.tar,不压缩(TAR 本身不压缩,压缩靠外层如 GZIP):
using SharpCompress.Writers;
using SharpCompress.Common;
<p>using (var writer = WriterFactory.Open("archive.tar", ArchiveType.Tar, CompressionType.None))
{
writer.Write("file1.txt", "path/to/file1.txt");
writer.Write("src/program.cs", "C:devprogram.cs"); // 注意:存档内路径用 /,自动处理
}说明:
- 第一个参数是归档内的路径名(
file1.txt或src/program.cs),第二个是磁盘上的真实路径 - 如果想加目录结构,就写带
/的名字,比如"docs/readme.md" - 若要生成
.tar.gz,把CompressionType.None换成CompressionType.GZip即可(文件名仍建议叫.tar.gz)
别混淆 TAR 和压缩:System.IO.Compression 不支持 TAR
System.IO.Compression 里的 GzipStream、DeflateStream 只负责字节流压缩,**不处理归档结构**。它们可以压缩单个文件,但无法把多个文件+元数据(权限、mtime、路径)打包成 TAR 格式。
典型误用:
- 用
GzipStream直接包装一堆文件字节 —— 结果是乱码,因为缺少 TAR header 和 block 对齐 - 以为
TarArchive类存在(它不存在,.NET 原生没有这个类) - 试图用
ZipArchive输出 .tar 扩展名 —— 文件实际仍是 ZIP 格式,Linuxtar -xf会报 “Unrecognized archive format”
TAR 的格式约束比看起来严格:512 字节块对齐、header checksum、typeflag 字段区分普通文件/目录/软链……这些都得由专用库处理,手撸极易出错。










