自己动手写Java虚拟机
上QQ阅读APP看书,第一时间看更新

2.3.5 WildcardEntry

WildcardEntry实际上也是CompositeEntry,所以就不再定义新的类型了。在ch02\classpath目录下创建entry_wildcard.go文件,在其中定义newWildcardEntry()函数,代码如下:

package classpath

import "os"
import "path/filepath"
import "strings"

func newWildcardEntry(path string) CompositeEntry {
baseDir := path[:len(path)-1] // remove *
compositeEntry := []Entry{}

walkFn := func(path string, info os.FileInfo, err error) error {...}
filepath.Walk(baseDir, walkFn)

return compositeEntry
}

首先把路径末尾的星号去掉,得到baseDir,然后调用filepath包的Walk()函数遍历baseDir创建ZipEntry。Walk()函数的第二个参数也是一个函数,了解函数式编程的读者应该一眼就可以认出这种用法(即函数可作为参数)。walkFn变量的定义如下:

walkFn := func(path string, info os.FileInfo, err error) error {
if err ! = nil {
  return err
}
if info.IsDir() && path ! = baseDir {
  return filepath.SkipDir
}
if strings.HasSuffix(path, ".jar") —— strings.HasSuffix(path, ".JAR") {
  jarEntry := newZipEntry(path)
  compositeEntry = append(compositeEntry, jarEntry)
}
return nil
}

在walkFn中,根据后缀名选出JAR文件,并且返回SkipDir跳过子目录(通配符类路径不能递归匹配子目录下的JAR文件)。