本页描述文件、文件序列和文件过滤器。使用的基本类型是 java.io.File,但一些方法通过隐式函数进行了扩展
sbt 使用 java.io.File 来表示文件,并定义了类型别名 File
用于 java.io.File
,因此不需要额外的导入。file
方法是单参数 File
构造函数的别名,用于简化从字符串构造新文件的操作
val source: File = file("/home/user/code/A.scala")
此外,sbt 为 File 扩展了 /
方法,它是用于构建路径的双参数 File
构造函数的别名
def readme(base: File): File = base / "README"
相对文件仅应在定义 Project
的基目录时使用,在那里它们将被正确解析。
val root = Project("root", file("."))
在其他地方,文件应为绝对路径,或从绝对基目录 File
构建。baseDirectory
设置定义了构建或项目的基目录,具体取决于范围。
例如,以下设置将非管理库目录设置为项目基目录中的“custom_lib”目录
unmanagedBase := baseDirectory.value /"custom_lib"
或者,更简洁地说
unmanagedBase := baseDirectory.value /"custom_lib"
此设置将 shell 历史记录的位置设置为构建的基目录,与定义该设置的项目无关
historyPath := Some( (ThisBuild / baseDirectory).value / ".history"),
PathFinder
在需要时计算 Seq[File]
。它是一种构建文件序列的方式。有一些方法会扩展 File
和 Seq[File]
来构造 PathFinder
。最终,在结果 PathFinder
上调用 get
来评估它并获取 Seq[File]
。
**
方法接受 java.io.FileFilter
并选择与该过滤器匹配的所有文件。
def scalaSources(base: File): PathFinder = (base / "src") ** "*.scala"
这将选择所有在 src
或子目录中以 .scala
结尾的文件。文件列表实际上直到调用 get
才会被评估
def scalaSources(base: File): Seq[File] = {
val finder: PathFinder = (base / "src") ** "*.scala"
finder.get
}
如果文件系统发生变化,对同一 PathFinder
对象的第二次 get
调用将反映这些变化。也就是说,get
方法每次都会重建文件列表。此外,get
仅返回在调用时存在的 File
。
选择作为子目录的直接子节点的文件可以使用单个 *
完成
def scalaSources(base: File): PathFinder = (base / "src") * "*.scala"
这将选择所有在 src
目录中以 .scala
结尾的文件。
如果对不表示目录的路径使用选择器,例如 /
、**
或 *
,路径列表将为空
def emptyFinder(base: File) = (base / "lib" / "ivy.jar") * "not_possible"
子节点和子孙选择器 *
和 **
的参数实际上是 NameFilter
。隐式函数用于将 String
转换为 NameFilter
,该过滤器将 *
解释为零个或多个任意值的字符。有关详细信息,请参阅下面的名称过滤器部分。
另一个操作是 PathFinder
的连接
def multiPath(base: File): PathFinder =
(base / "src" / "main") +++
(base / "lib") +++
(base / "target" / "classes")
使用 get
评估时,这将返回 src/main/
、lib/
和 target/classes/
。连接的查找器支持所有标准方法。例如,
def jars(base: File): PathFinder =
(base / "lib" +++ base / "target") * "*.jar"
选择“lib”和“target”目录中的所有 jar 文件。
一个常见的问题是排除版本控制目录。这可以通过以下方法实现
def sources(base: File) =
( (base / "src") ** "*.scala") --- ( (base / "src") ** ".svn" ** "*.scala")
第一个选择器选择所有 Scala 源代码,第二个选择器选择所有作为 .svn
目录子孙的源代码。---
方法从第一个选择器返回的文件序列中删除第二个选择器返回的所有文件。
有一个 filter
方法接受类型为 File => Boolean
的谓词,并且是非严格的
// selects all directories under "src"
def srcDirs(base: File) = ( (base / "src") ** "*") filter { _.isDirectory }
// selects archives (.zip or .jar) that are selected by 'somePathFinder'
def archivesOnly(base: PathFinder) = base filter ClasspathUtilities.isArchive
PathFinder.empty
是一个 PathFinder
,在调用 get
时返回空序列
assert( PathFinder.empty.get == Seq[File]() )
使用以下方法之一将 PathFinder
转换为 String
toString
用于调试。它将每个组件的绝对路径放在单独的行上。absString
获取每个组件的绝对路径,并用平台的路径分隔符分隔它们。getPaths
生成包含每个组件的绝对路径的 Seq[String]
sbt 中的打包和文件复制方法分别期望类型为 Seq[(File,String)]
和 Seq[(File,File)]
的值。这些是输入文件与其在 jar 文件中的(String)路径或其(File)目标的映射。这种方法替换了早期 sbt 版本中使用的相对路径方法(使用 ##
方法)。
映射在 Mapping-Files
页面上有详细的讨论。
*
和 **
的参数的类型是 java.io.FileFilter。sbt 提供了用于构造 FileFilter
的组合器。
首先,String 可以隐式转换为 FileFilter
。结果过滤器选择名称与字符串匹配的文件,字符串中的 *
解释为通配符。例如,以下代码选择所有包含单词“Test”的 Scala 源代码
def testSrcs(base: File): PathFinder = (base / "src") * "*Test*.scala"
FileFilter
中添加了一些有用的组合器。||
方法声明了备选 FileFilter
。以下示例选择“src”下的所有 Java 或 Scala 源代码文件
def sources(base: File): PathFinder = (base / "src") ** ("*.scala" || "*.java")
--
方法从第一个过滤器匹配的文件中排除与第二个过滤器匹配的文件
def imageResources(base: File): PathFinder =
(base/"src"/"main"/"resources") * ("*.png" -- "logo.png")
例如,这将获取 right.png
和 left.png
,但不会获取 logo.png
。