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

mts*_*kol 8 scala sbt

我有一个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+作品上构建罐子读取文件getResourceAsStream作品完美,但因我的问题而失败)

感谢您提供的帮助和解决方法!

Mar*_*lic 7

run任务似乎已在正向运行任务中重新连接到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
Run Code Online (Sandbox Code Playgroud)

代替

file:/Users/amani/IdeaProjects/sbt-resource-bug/target/scala-2.12/classes/my-dir
Run Code Online (Sandbox Code Playgroud)

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

作为一种解决方法,我们可以尝试build.sbt像这样恢复重新布线:

run := Defaults.runTask(fullClasspath in Runtime, mainClass in run in Compile, runner in run).evaluated
Run Code Online (Sandbox Code Playgroud)

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

new File(getClass.getResource("/my-dir").getFile).listFiles().foreach(println)
Run Code Online (Sandbox Code Playgroud)

应该输出

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
Run Code Online (Sandbox Code Playgroud)

 解决方法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)
  }
}
Run Code Online (Sandbox Code Playgroud)

然后

ListFileNamesInJarDirectory("my-dir").foreach(println)
Run Code Online (Sandbox Code Playgroud)

应该输出

my-dir/file1.txt
my-dir/file2.txt
Run Code Online (Sandbox Code Playgroud)

之后,getResourceAsStream可以用来获取jar中的实际文件。注意我们如何File表示jar文件:

val jar = new File(getClass.getProtectionDomain().getCodeSource().getLocation().getPath())
Run Code Online (Sandbox Code Playgroud)