Skip to content

Commit

Permalink
Use Files.isHidden instead of File.isHidden
Browse files Browse the repository at this point in the history
On linux/osx, a file is considered hidden if its name starts with ".".
Unfortunately, java.io.File.isHidden checks the file system for a hidden
file attribute instead of just checking if the path starts with '.'.
This check takes O(10us) per file, which can lead to noticeable latency
if there are may files to be checked. The java.nio.file.Files.isHidden
method just checks if the path starts with "." on linux/osx and does
whatever it needs to do on windows.

I don't really understand what the point of the file.getName != "."
check is since "." is clearly a hidden file and in most use cases I can
think of, you'd want to exclude it where you exclude other files. But
since I'm not sure what the point is, I'm leaving it alone.

Bonus: annotate type signature of public methods (to quiet intellij)
  • Loading branch information
eatkins committed Sep 26, 2018
1 parent 55349cf commit 04fe874
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions io/src/main/scala/sbt/io/NameFilter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
*/
package sbt.io

import java.io.File
import java.io.{ File, IOException }
import java.nio.file.Files
import java.util.regex.Pattern

import scala.language.implicitConversions

/** A `java.io.FileFilter` with additional methods for combining filters. */
Expand Down Expand Up @@ -69,19 +71,21 @@ trait NameFilter extends FileFilter {

}

/** A [[FileFilter]] that selects files that are hidden according to `java.io.File.isHidden` or if they start with a dot (`.`). */
/** A [[FileFilter]] that selects files that are hidden according to `java.nio.file.Files.isHidden` or if they start with a dot (`.`). */
object HiddenFileFilter extends FileFilter {
def accept(file: File) = file.isHidden && file.getName != "."
def accept(file: File): Boolean =
try Files.isHidden(file.toPath) && file.getName != "."
catch { case _: IOException => false }
}

/** A [[FileFilter]] that selects files that exist according to `java.io.File.exists`. */
object ExistsFileFilter extends FileFilter {
def accept(file: File) = file.exists
def accept(file: File): Boolean = file.exists
}

/** A [[FileFilter]] that selects files that are a directory according to `java.io.File.isDirectory`. */
object DirectoryFilter extends FileFilter {
def accept(file: File) = file.isDirectory
def accept(file: File): Boolean = file.isDirectory
}

/** A [[FileFilter]] that selects files according the predicate `acceptFunction`. */
Expand All @@ -91,7 +95,7 @@ sealed class SimpleFileFilter(val acceptFunction: File => Boolean) extends FileF

/** A [[NameFilter]] that accepts a name if it is exactly equal to `matchName`. */
final class ExactFilter(val matchName: String) extends NameFilter {
def accept(name: String) = matchName == name
def accept(name: String): Boolean = matchName == name
override def toString = s"ExactFilter($matchName)"
}

Expand All @@ -102,7 +106,7 @@ sealed class SimpleFilter(val acceptFunction: String => Boolean) extends NameFil

/** A [[NameFilter]] that accepts a name if it matches the regular expression defined by `pattern`. */
final class PatternFilter(val pattern: Pattern) extends NameFilter {
def accept(name: String) = pattern.matcher(name).matches
def accept(name: String): Boolean = pattern.matcher(name).matches
override def toString = s"PatternFilter($pattern)"
}

Expand Down

0 comments on commit 04fe874

Please sign in to comment.