Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Pathikrit Bhowmick
    @pathikrit
    you will just inputstream.autoclosed.map(doSomething) in 3.1
    Craig Giles
    @CraigGiles
    Hey everyone. When working with better-files, we developed a feature that works in all of our unit tests but fails the moment we package up the app in a docker container. It's giving us a FileSystemNotFoundException with version v3.0.0. I saw there is a PR that should have been merged that addresses something along these lines, but does anyone else have any ideas why the ZipFileSystemProvider.getFileSystem would throw this error?
    Christian Kaps
    @akkie

    I use the FileWatcher service in a Play application. Every time the application reloads I get a ClosedWatchServiceException:

    java.nio.file.ClosedWatchServiceException: null
            at sun.nio.fs.AbstractWatchService.checkOpen(Unknown Source)
            at sun.nio.fs.AbstractWatchService.checkKey(Unknown Source)
            at sun.nio.fs.AbstractWatchService.take(Unknown Source)
            at better.files.FileMonitor.$anonfun$start$2(FileMonitor.scala:56)
            at scala.collection.Iterator$$anon$9.next(Iterator.scala:161)
            at scala.collection.Iterator.foreach(Iterator.scala:929)
            at scala.collection.Iterator.foreach$(Iterator.scala:929)
            at scala.collection.AbstractIterator.foreach(Iterator.scala:1417)
            at better.files.FileMonitor.$anonfun$start$1(FileMonitor.scala:56)
            at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)

    I could register a shutdown hook, but I have no idea how I can shutdown the watcher service gracefully. Any idea how I can fix this?

    Marcos Pereira
    @marcospereira
    Hey guys, looking at pathikrit/better-files#40.
    If I understand it correctly, the fix it is not closing the DirectoryStream automatically, but instead giving users control over it.
    Is that right?
    Marcos Pereira
    @marcospereira
    Peter Schmitz
    @petomat

    Hey. I am new to this library. FileMonitorgot me hooked. But what I am doing wrong?:

    package example
    
    import better.files.File
    import better.files.FileMonitor
    
    object Hello extends App {
    
      val pwd = File.currentWorkingDirectory
      val watcher = new FileMonitor(pwd, recursive = true) {
        override def onCreate(file: File, count: Int) = println(s"$file got created")
        override def onModify(file: File, count: Int) = println(s"$file got modified $count times")
        override def onDelete(file: File, count: Int) = println(s"$file got deleted")
      }
      import scala.concurrent.ExecutionContext.Implicits.global
      watcher.start()
      val f = pwd / "test.txt"
      f.delete()
      Thread.sleep(1000)
      f.touch()
      Thread.sleep(1000)
      watcher.stop()
    
    }

    gives a java.nio.file.ClosedWatchServiceException when stopping the watcher. And more importantly touching the file (tested even writing) does not trigger the onCreate method. What's wrong?

    I am using scala 2.12.4 and better-files 3.2.0
    som-snytt
    @som-snytt
    FWIW, I had the question from last May about getting a value out. I just wanted to for (x <- tempDIr() ; y <- tempDir()) yield test in a scalacheck. To avoid extra parens and .get, I added a local conversion to Prop.
    som-snytt
    @som-snytt
    Thought I'd add that sometimes the scalacheck property is lazily computed and your resource is closed by then. (I guess I can see the old-timey appeal of resource management tied to finalize.) I noticed it when adding "labels" to parts of a boolean expr in scalacheck.
    scalway
    @scalway

    Hello. I see in code such things.

      def symbolicLinkTo(destination: File)(implicit attributes: File.Attributes = File.Attributes.default): destination.type = {
        Files.createSymbolicLink(path, destination.path, attributes: _*)  // <-- here
        destination
      }
    
      def linkTo(destination: File, symbolic: Boolean = false)(implicit attributes: File.Attributes = File.Attributes.default): destination.type = {
        if (symbolic) {
          symbolicLinkTo(destination)(attributes)
        } else {
          Files.createLink(destination.path, path) // <-- here
          destination
        }
      }

    both functions linkTo and symbolicLinkTo has reversed arguments. Why? It is a Bug? This is weird for me.

    megri
    @megri

    Heya! I need to load resources dynamically from a directory on the jar-classpath. My application along with its resources is packaged as a fat-jar (using sbt-assembly). As it turns out, getResourceAsStream(dirName) returns an empty stream — it works if the application is not packaged.

    Can better-files handle this scenario? I've found a potential Java-solution here but it's quite complex and doesn't handle resource deallocation or exceptions.

    Pathikrit Bhowmick
    @pathikrit
    @megri : Yes: pathikrit/better-files#227
    Philippe Derome
    @phderome
    Do people use this project in conjunction with HDFS?
    megri
    @megri
    @pathikrit Pretty sure that won't handle jared files
    Maxim Moseychuk
    @fshp
    Hi! How to up ManagedResource from list?
    List[ManagedResources[File]] => ManagedResources[List[File]]

    I wrote

      implicit object ManagedResourceApplicative extends Applicative[ManagedResource] {
    
        override def pure[A](x: A): ManagedResource[A] = {
          implicit val  disposer: better.files.Disposable[A] = better.files.Disposable[A]((_: A) => {})
          new ManagedResource(x)
        }
    
        override def ap[A, B](ff: ManagedResource[A => B])(fa: ManagedResource[A]): ManagedResource[B] = {
          for {
            f <- ff
            a <- fa
          } yield f(a)
        }
      }

    with use cats

    And use

    val mFiles: List[ManagedResource[File]] = ...
    
    for {
      files <- mFiles.sequence
    } doSomesing

    Its work. But I'm not sure it's right.

    Dermot Haughey
    @hderms
    is there a way to glob resources?
    Pathikrit Bhowmick
    @pathikrit
    @hderms : Not in better-files currently. Can you file an issue about what you want?
    @/all : snapshot versions of better-files for scala 2.13.0-M4 is now available: https://oss.sonatype.org/content/repositories/snapshots/com/github/pathikrit/better-files_2.13.0-M4/
    Ryan Stull
    @ryanstull

    Hey, does anyone know of a way to handle malformed characters when using better files?
    I'm getting this error

    Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1
    at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at java.nio.file.Files.readAllLines(Files.java:3205)
    at better.files.File.lines(File.scala:282)

    Ryan Stull
    @ryanstull
    For future reference, I found a way to work around it. Not the prettiest but it works:
    def linesSkipMalformed(file: File)(implicit charset: Charset = better.files.DefaultCharset): Traversable[String] = {
            @throws[IOException]
            def skippingBufferedReader(path: Path, cs: Charset): BufferedReader = {
                val decoder = cs.newDecoder.onMalformedInput(CodingErrorAction.IGNORE)
                val reader = new InputStreamReader(Files.newInputStream(path), decoder)
                new BufferedReader(reader)
            }
    
            @throws[IOException]
            def readAllLines(path: Path, cs: Charset): util.List[String] = {
                val reader: BufferedReader = skippingBufferedReader(path,cs)
                val result: util.List[String] = new util.ArrayList[String]
    
                var line: String = ""
                do {
                    line = reader.readLine
                    if(line != null) result.add(line)
                } while(line != null)
    
                if(reader != null) reader.close()
    
                result
            }
    
            readAllLines(file.path,charset).asScala
        }
    Pathikrit Bhowmick
    @pathikrit
    Can you file an issue ^
    legopiraat
    @legopiraat
    Hello Everyone,
    Currently in a project am using BetterFiles and am very pleased by it! But am missing a feature that would be nice to have.
    Currently i have the use case to copy over files to a newly created tmp folder. But i don't want to copy the files on a 1 to 1 bases. I would like to ignore some directories but i can't find a good way to do this.
    Like match something based on a regex and exclude those. Is there a way to do this?
    legopiraat
    @legopiraat
    for example:
      val tmpDir: File = File.newTemporaryDirectory("tmp-")
      val path: File = config.baseDir
      path.copyTo(tmpDir, exclude = "\\bgit\\b")
    Pathikrit Bhowmick
    @pathikrit
    @legopiraat : that is too much of a specific use case I think. What would probably help is to have copyTo have a filter File => Boolean option to accept or reject. But, then you can see that so many other APIs would deserve that filter and not just copyTo and now we made the interface of better-files crazy because of your one use case.
    legopiraat
    @legopiraat
    The reason i asked for this is because am unable to delete some files after i copy them to the tmp folder
    Pathikrit Bhowmick
    @pathikrit
    what you can do is path.listRecursively.filterNot(_.name.matches(regex)).foreach(f => f.copyTo(tmpDir / (path.relativize(f).path)))
    legopiraat
    @legopiraat
    oow! that's an excellent idea! Didn't even think of that :)
    Jason Shin
    @JasonShin
    Hey guys
    package services
    import javax.inject._
    import sun.misc.{ BASE64Encoder, BASE64Decoder }
    import better.files.{File => ScalaFile}
    import java.io.{ FileInputStream, FileOutputStream }
    import org.apache.commons.codec.binary.Base64
    import com.google.common.io.CharStreams
    import java.io.{ InputStream, InputStreamReader }
    import com.google.common.base.Charsets
    
    /**
      * FileEncoder.scala
      *
      * Context:
      * The service aim to provide easy-to-use file R/W operations throughout Stormwind.io code base.
      * It will have utilities such as getActionAsBase64
      */
    class FileSystem () {
      /**
        * Map ScalaFile to File for test mocking
        */
      val File = ScalaFile
      /**
        * Read file as a string
        *
        * @example
        * val fs = new FileSystem
        * fs.readFileAsString("~/tmp/test.txt")
        * // returns a base64 representation of the file
        *
        * @param path
        * @return
        * @sideEffect
        */
      def readFileAsString(path: String): String = {
        // Reading the file as a FileInputStream
        val fileInputStream = new FileInputStream(File(path).toJava)
        // TODO: Is there a way to read as Bytes directly?
        val str = CharStreams.toString(new InputStreamReader(fileInputStream, Charsets.UTF_8))
        return str
      }
    
      /**
        * Zips an action if a zip file under the action directory doesn't already exist
        * Also you can forcefully zip the task, which deletes already existing ones
        *
        * @example
        * fs.zipDirIfNotExist("github", "triggers", "list_webhooks")
        * // creates a zip file under tasks/github/list_webhooks/list_webhooks.zip
        *
        * @param appName
        * @param taskType
        * @param taskName
        * @param force - Forcefully delete the existing zip file
        */
      def zipTaskIfNotExist(
        appName: String,
        taskType: String,
        taskName: String,
        force: Boolean = true
      ): Boolean = {
        val pwd = System.getProperty("user.dir")
        val dirPath = s"${pwd}/tasks/${appName}/${taskType}/${taskName}"
        val zipPath = s"${dirPath}/${taskName}.zip"
        val dir = File(dirPath)
        val zipFile = File(zipPath)
        if (force && zipFile.exists()) {
          zipFile.delete()
        }
    
        if (!zipFile.exists()) {
          dir.zipTo(zipFile.path)
        }
        true
      }
    
      /**
        * Get the zip folder of action as Base64.
        * This is typically need to interact with the OpenWhisk API for creating actions
        * by passing in the base64 representation of the ZIP file.
        *
        * @example
        * val fs = new FileSystem
        * // Execution of the code below return a base64 representation of the task
        * val result = fs.getActionAsBase64("github", "triggers", "list_webhooks")
        *
        * @param appName - application name such as Github
        * @param taskType - taskType can be either actions or triggers
        * @param taskName - name of the task such as create_issue
        * @return
        */
      def getActionAsBase64(
        appName: String,
        taskType: String,
        taskName: String,
        // Use the default method if possible
        readFileAsString: (String) => String = this.readFileAsString
      ): String = {
        val pwd = System.getProperty("user.dir")
        val dirPath = s"${pwd}/tasks/${appName}/${taskType}/${taskName}"
        val zipPath = s"${dirPath}/${taskName}.zip"
    
        val content: String = readFileAsString(zipPath)
        // Encoding the file using Base64encoder
        val encoded = new BASE64Encoder().encode(content.getBytes(Charsets.UTF_8))
        return encoded.toString
      }
    }
    I have above class in my source code
    and I am trying to write unit test for zipTaskIfNotExist; how would you mock ScalaFile or how would you write a unit test for it?
    I'm currently apporaching it like
    
    class FakeFile(val path: String) {
      def exists(): Boolean = {
        if (path.endsWith(".zip")) {
          return true
        } else {
          return true
        }
      }
      def delete(): Unit = {}
    }
    
    /**
      * Unit tests can run without a full Play application.
      */
    class FileSystemSpec extends PlaySpec {
    
        "zipTaskIfNotExist" should {
          "return true without errors" in {
    
            val fs = new FileSystem {
              override val File = FakeFile
            }
    
            val result = fs.zipTaskIfNotExist("github", "hello", "zz")
            result must equal(true)
          }
        }
    
      }
    }
    But the compiler is complaining
    [error] /home/jason/Desktop/stormwind.io/test/unit/services/FileSystemSpec.scala:53:31: not found: value FakeFile
    [error]           override val File = FakeFile
    [error]                               ^
    [error] one error found
    Pathikrit Bhowmick
    @pathikrit
    i don't understand what is FakeFile either
    Pathikrit Bhowmick
    @pathikrit
    /all better-files is now released for Scala 2.13.0-M5
    moritz bust
    @busti
    Is there an operator that creates a file and then writes to it?
    moritz bust
    @busti
    Also, I would like to clear the contents of a folder and then Immediately write to it. However, this causes an AccessDeniedError to be thrown when writing contents to the, now empty, folder.
    Pathikrit Bhowmick
    @pathikrit

    Is there an operator that creates a file and then writes to it?

    Yes, file.createIfNotExits().write("hello")

    AccessDeniedError means you don't have permission to write to that folder. This is not coming from better-file but from the JDK std lib itself (in the case of I/O from the OS itself)
    moritz bust
    @busti
    Yeah, the thing is, that the first .delete call is successful in deleting the folder but I cannot create any new folder / files in that location until I have restarted the jvm.
    moritz bust
    @busti
    When I recursively delete the files using java.nio it works perfectly fine.
    def deleteAll(file: java.io.File) {
      val contents = file.listFiles()
      if (contents != null) {
        for (f <- contents) {
          FileUtil.deleteAll(f)
        }
      }
     file.delete()
    }
    Pathikrit Bhowmick
    @pathikrit
    Can you paste me your better-files code that does not work and the accompanying NIO code that works? They should do the same thing
    Kunal Kapoor
    @kunalkapoor
    Hey guys I'm new here. I've been looking for a good File IO library for Scala for a long time and I came across this recently. It looks very attractive.
    I also stumbled across https://contributors.scala-lang.org/t/adding-better-files-to-the-scala-platform/340/31 which mentions that better-files could be included in the Scala library itself. However, there is no response since Feb 2017 so I was curious as to the status of that. We all know Scala desperately needs a good IO library, and I'm wondering whether better-files is still on the road to becoming the standard Scala IO utility.
    Pathikrit Bhowmick
    @pathikrit
    There is no plan for better-files becoming part of Scala standard library. Honestly it is better this way since libraries can release improvements/features faster than Scala standard release cadence
    Kunal Kapoor
    @kunalkapoor