你使用的Go版本是什么( go version
)?
$ go version
go version go1.17 linux/amd64
这个问题在最新版本中是否重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/user/go/pkg/mod"
GOOS="linux"
GOPATH="/home/user/go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2958766942=/tmp/go-build -gno-record-gcc-switches"
你做了什么?
https://play.golang.org/p/-MVV8qRhxxC 大致如下:
r, _ := NewReader(b, len)
f, _ := r.Open("path/to/dir")
s, _ := f.Stat()
fmt.Print(s.Mode())
你期望看到什么?
drw-rw-rw-
(来自 zip.File.FileHeader.Mode()
的推导)
你看到了什么?
dr-xr-xr-x
额外的上下文?
似乎 Reader.Open
,特别是 fileListEntry.Mode
的实现,而不是返回 fileListEntry.file.FileHeader.Mode
中实际包含的模式,而是返回一个硬编码的 fs.FileMode
:
package zip // import "archive/zip"
func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }
我猜想,但看起来这是因为 fileListEntry.file
在目录条目为合成时可以是 nil
,例如zip文件包含一个没有目录文件指向它的文件,参见 #48084 。
如果我们想一举两得,因为这将是一个明确的信号表明“目录文件丢失”,我认为合理的方法是:(尽管这是一个破坏性的变化)
package zip // import "archive/zip"
func (f *fileListEntry) Mode() fs.FileMode {
if f.file == nil {
return 0
}
return f.file.FileHeader.Mode
}
3条答案
按热度按时间hec6srdp1#
cc @rolandshoemaker@dsnet
f4t66c6m2#
我认为目录的可执行位通常意味着你可以进入该目录,所以对我来说0555是有意义的。你为什么期待
drw-rw-rw-
?0555来自CL https://go-review.googlesource.com/c/go/+/243937.cc @rsc
5lhxktic3#
所以,这是一个不太好的复制器,因为我同时使用了
Writer.Create
作为文件和目录的模式,因此我们得到了一个"默认"模式。我可以很高兴地修改示例以进行完整的Writer.CreateHeader
并设置自定义模式,但这似乎是一个最小可行的复制器。我的评论并不是说
drw-rw-rw-
(0o20000000555
)比drw-rw-rw-
(0o20000000666
)更好或更差,而是说存储在b
中的zip字节定义了dir/
具有drw-rw-rw-
的模式,因此这就是archive/zip
应该为Reader.File
和Reader.Open
返回的内容。