gpt4 book ai didi

scala - 列出 sbt 1.2.8 中资源目录中的文件

转载 作者:行者123 更新时间:2023-12-02 05:14:26 25 4
gpt4 key购买 nike

我有一个 Scala 应用程序,它处理 resources 中某个目录中的二进制文件。我想将此目录获取为 java.io.File 并列出所有内容。在最新的 sbt 中,我无法直接做到这一点。

我已经针对我的问题创建了最小的存储库:

https://github.com/mat646/sbt-resource-bug

sbt 0.13.18 及更低版本不会出现此问题。因此,经过一些研究,我发现自 sbt 1.0 以来,设计发生了变化,并且此类问题已在此处得到解决:

https://github.com/sbt/sbt/issues/3963

因此提供的解决方案是:

  1. 降级到 sbt 0.13(我想避免)
  2. 提取项目 jar 本身(我发现这很烦人,因为我还没有解决它 - https://github.com/sbt/io 包含 gunzip 方法,但对我来说它仍然无法从 jar 中提取我的目录,但在这里我可能误解了如何从项目 jar 中提取嵌套文件)
    (因此,由于 sbt 1.0+ 在构建 jar 上工作以读取文件 getResourceAsStream 工作完美,但对我的问题失败)

最佳答案

run 任务似乎已在 Forward run task to bgRun #3477 中重新连接一个副作用是在类路径而不是类目录上使用打包的 jar,以便 getClass.getResource("/my-dir") 返回

jar:file:/var/folders/84/hm7trc012j19rbgtn2h4fg6c0000gp/T/sbt_1397efb8/job-1/target/43a04671/sbt-resource-bug_2.12-0.1.jar!/my-dir

而不是

file:/Users/amani/IdeaProjects/sbt-resource-bug/target/scala-2.12/classes/my-dir

解决方法 1:将 run 重新定义为旧行为

作为解决方法,我们可以尝试在 build.sbt 中恢复重新布线,如下所示:

run := Defaults.runTask(fullClasspath in Runtime, mainClass in run in Compile, runner in run).evaluated

现在File.listFiles应该可以工作,例如,

new File(getClass.getResource("/my-dir").getFile).listFiles().foreach(println)

应该输出

sbt:sbt-resource-bug> run
[info] Running Main
/Users/mario/IdeaProjects/sbt-resource-bug/target/scala-2.12/classes/my-dir/file2.txt
/Users/mario/IdeaProjects/sbt-resource-bug/target/scala-2.12/classes/my-dir/file1.txt

 解决方法 2:使用 JarFile 直接使用 JAR

或者,如果我们希望保留当前的重新布线,JarFile可用于列出 JAR 文件的内容。例如,给定

object ListFileNamesInJarDirectory {
def apply(dir: String): List[String] = {
import scala.collection.JavaConverters.enumerationAsScalaIteratorConverter
val jar = new File(getClass.getProtectionDomain().getCodeSource().getLocation().getPath())
(new JarFile(jar))
.entries()
.asScala
.toList
.filter(!_.isDirectory)
.filter(entry => entry.getRealName.contains(dir))
.map(_.getName)
}
}

然后

ListFileNamesInJarDirectory("my-dir").foreach(println)

应该输出

my-dir/file1.txt
my-dir/file2.txt

之后,可以使用getResourceAsStream来获取jar中的实际文件。注how我们得到 File 来表示 jar 文件:

val jar = new File(getClass.getProtectionDomain().getCodeSource().getLocation().getPath())

关于scala - 列出 sbt 1.2.8 中资源目录中的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55493096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com