背景
tar文件是一种用于归档文件系统的格式,能够表示包括常规文件、目录、块设备和字符设备、符号链接和硬链接在内的任何内容。
多年来,许多与tar不兼容的扩展已经成为常见做法。具体来说,其中一个是使用伪文件来编码关于一个文件或一组文件的额外信息。伪文件以与普通文件相同的方式编码,但Header.Typeflag
被设置为某个特殊值,文件的内容根据由typeflag确定的某种格式进行解析。GNU和PAX格式都是这种方法的重度用户。
Go实现的tar为描述其实际文件的伪文件提供自动解析元数据的功能。例如,Go1.1支持解析GNU格式的长文件名;Go1.3支持解析本地PAX头;Go1.3还支持解析GNU稀疏头。
问题
解析单个文件的元数据在API中很容易表示,因为我们只需在Header结构中表示附加信息即可。
然而,PAX格式添加了一个名为“全局PAX头”的功能,该功能编码了旨在修改所有后续文件的元数据(#22748表示实际上使用了此功能;例如,git archive --format=tgz
生成它们)。
为了提供包含全局PAX头中的元数据,Reader.Next
返回一个表示伪文件的单个Header
(在go1.10中,我们实际上将PAX记录解析为Header.PAXRecords
,但这与此问题无关)。
全局头(以及Go实现确实不识别的任何typeflag)的问题在于:
Header{Typeflag: TypeXGlobalHeader}.FileInfo().Mode().IsRegular() // true
这是迄今为止所有版本的Go的行为。IsRegular
报告为真的问题是:
- 它不真实。这不是一个常规文件。
- 仅依赖于
Header.FileInfo
的用户无法特别处理伪文件(例如,忽略它们)。
然而,要使Header.FileInfo.Mode.IsRegular
报告为假并非易事,因为os.FileMode.IsRegular
的逻辑仅对非常狭窄的类型集报告为假,这些类型中没有一个是像元数据或未识别的typeflag这样的“特殊”文件的明显选择。
因此,我们需要决定是否保留或更改当前针对像TypeXGlobalHeader
这样的特殊文件的Header.FileInfo.Mode.IsRegular
的行为。如果我们改变它,如何让它报告为假?我认为唯一的方法是在os
包中定义一个新的常量(例如,ModeSpecial
)。
想法?
\cc @rasky@bradfitz
3条答案
按热度按时间xpszyzbs1#
嗯,挺糟糕的。
如果os.ModeSpecial定义得模糊一些,我也能接受。
我们也可以在archive/tar中记录这些头文件的存在。
实际上,我更倾向于默认跳过这样的东西,并让甚至遍历它们成为可选操作。现在可能太晚了才这样做。添加一个可选开关可能没什么用,因为即使他们知道tar格式(我之前不知道),人们也可以自己检查
Header.Typeflag
和continue
。但我假设大多数人不知道这些,也不想看到它们,所以我会尝试使用可选开关。我们需要在GitHub和谷歌上搜索,看看nobody-cares理论是否正确。xesrikrc2#
我投票给
os.ModeSpecial
。我认为选择加入的方法也是一个好主意,但我认为它与
ModeSpecial
无关。我认为让用户使用os.FileMode
进行文件处理仍然有价值,而不必强制他们切换到Header.Typeflag
,除非严格要求。kyvafyod3#
https://golang.org/cl/94856提到了这个问题:
os: add ModeUnknown flag