Listing files from resource directory in sbt 1.2.8

后端 未结 1 1001
一整个雨季
一整个雨季 2021-01-11 15:13

I have a Scala application which processes binary files from some directory in resources. I would like to get this directory as java.io.File and li

相关标签:
1条回答
  • 2021-01-11 15:57

    run task seems to have been rewired in Forward run task to bgRun #3477 and one side-effect was to use packaged jars on classpaths instead of class directories, so that getClass.getResource("/my-dir") returns

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

    instead of

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

    Workaround 1 : Redefine run to the old behaviour

    As a workaround, we could try reverting the rewiring in our build.sbt like so:

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

    Now File.listFiles should work, for example,

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

    should output

    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
    

     Workaround 2: Use JarFile to work with JARs directly

    Alternatively, if we wish to keep the current rewiring, JarFile can be used to list the contents of JAR files. For example, given

    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)
      }
    }
    

    then

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

    should output

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

    Afterwards, getResourceAsStream can be used to get at the actual files in the jar. Note how we get File to represent the jar file:

    val jar = new File(getClass.getProtectionDomain().getCodeSource().getLocation().getPath())
    
    0 讨论(0)
提交回复
热议问题