Ensure directories exist

I’m using java.io to create a file. I’d like to ensure that the leading directories exist in order to avoid an error such as

generating target/temperatures/average/2/earth-scatter-month-2015.png
Exception in thread "main" java.io.IOException: No such file or directory
	at java.io.UnixFileSystem.createFileExclusively(Native Method)
	at java.io.File.createNewFile(File.java:1012)
	at globe.EarthMap.output(EarthMap.scala:157)

Is there something like ensureDirectoriesExist(file) where I can give the name of the file I want to create, or do I really need to parse out the name of the directory myself and check explicitly whether the directory exists, creating if necessary?

  def output(fileName: String):Boolean = {
    if (borders) {
      Borders.drawBorders(this,drawGeodesic(_,_,colorBlack))
    }
    import javafx.embed.swing.SwingFXUtils._
    import javax.imageio.ImageIO.write
    val file = new java.io.File(fileName)
    println(s"generating $file")
    ///  TODO, I want to ensure the directory exists otherwise file creation will fail
    write(fromFXImage(wimg,null),"png", file)
  }

I’ve discovered I can use file.getParentFile().mkdirs() and that will create the directories leading to the intended file. Perhaps that’s the correct solution?

2 Likes

That is the solution that I have used in the past. I’m not certain if it is the ideal solution, but it seems to work well.

1 Like

@MarkCLewis, this code no longer works. Do you know whether its simply of matter of updating my build.sbt, or whether the issue is more serious? I asked the same question elsewhere on this forum. what about javafx

It is really odd that isn’t working. That is a Java library. It has nothing to do with Scala. So if it isn’t working it implies something about the JVM you are using, but I’m not certain what. That code has done what you want in Java since the mid-90s without alteration.

1 Like

Thanks for the clue. Any idea how to ask intellij or sbt which version of java its using? I get the same error when I run sbt from the shell command line.

Is it just the version of java available at the shell?

[geminiani:~/Repos/mgs] jimka% java --version
java 14 2020-03-17
Java(TM) SE Runtime Environment (build 14+36-1461)
Java HotSpot(TM) 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)
[geminiani:~/Repos/mgs] jimka%

As I already explained elsewhere, I’ve added the following lines to my build.sbt, and at least the project compiles. I haven’t yet tested to see if it works, but at least it compiles.

lazy val osName = System.getProperty("os.name") match {
  case n if n.startsWith("Linux") => "linux"
  case n if n.startsWith("Mac") => "mac"
  case n if n.startsWith("Windows") => "win"
  case _ => throw new Exception("Unknown platform!")
}

// Add JavaFX dependencies
lazy val javaFXModules = Seq("base", "controls", "fxml", "graphics", "media", "swing", "web")
libraryDependencies ++= javaFXModules.map( m=>
  "org.openjfx" % s"javafx-$m" % "11" classifier osName
)

cf - https://stackoverflow.com/questions/57628274/sbt-wont-compile-helloworld-scalafx-example-complains-about-javafx-missing-fro/57628433#57628433

I really find this to be an unusual bug if those directories aren’t being created. Java 14 is rather bleeding edge right now though. I’d probably try just doing a jshell and running a call to mkdirs from there to see if it works in Java. That would give me something to go on in terms of where the real issue is. If it is in the JVM then your only option is probably rolling back to an earlier version. Personally, I’ve switched all my stuff to Graal and they only have Java 8 and Java 11 right now.

1 Like