pathikrit / better-files Goto Github PK
View Code? Open in Web Editor NEWSimple, safe and intuitive Scala I/O
Home Page: https://pathikrit.github.io/better-files/
License: MIT License
Simple, safe and intuitive Scala I/O
Home Page: https://pathikrit.github.io/better-files/
License: MIT License
Information:15/11/15 下午9:36 - Compilation completed with 2 errors and 0 warnings in 2s 754ms
Error:scalac:
while compiling: /Users/xbsu/workspace/demo/file-demo/src/main/scala/cn/thinkjoy/scala4fun/file/FileApp.scala
during phase: erasure
library version: version 2.10.4
compiler version: version 2.10.4
reconstructed args: -nobootcp -target:jvm-1.5 -javabootclasspath : -classpath /Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/lib/javafx-doclet.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/lib/tools.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/htmlconverter.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Users/xbsu/workspace/demo/file-demo/target/classes:/Users/xbsu/.m2/repository/org/scala-lang/scala-library/2.10.4/scala-library-2.10.4.jar:/Users/xbsu/.m2/repository/org/scala-lang/scala-reflect/2.10.4/scala-reflect-2.10.4.jar:/Users/xbsu/.m2/repository/com/github/pathikrit/better-files_2.10/2.13.0/better-files_2.10-2.13.0.jar:/Users/xbsu/.m2/repository/org/scala-lang/scala-library/2.10.5/scala-library-2.10.5.jar:/Users/xbsu/.m2/repository/org/scala-lang/scala-compiler/2.10.4/scala-compiler-2.10.4.jar
last tree to typer: ArrayValue
symbol: null
symbol definition: null
tpe: Array[String]
symbol owners:
context owners: value args -> method main -> object FileApp -> package file
== Enclosing template or block ==
DefDef( // def main(args: Array[String]): Unit in object FileApp
<method>
"main"
[]
// 1 parameter list
ValDef( // args: Array[String]
<param>
"args"
<tpt> // tree.tpe=Array[String]
<empty>
)
<tpt> // tree.tpe=runtime.BoxedUnit
Block( // tree.tpe=Unit
Apply( // def lines(codec: scala.io.Codec): Iterator[String] in class File, tree.tpe=Iterator[String]
{
val qual$2: better.files.File = {
val qual$1: better.files.File = better.files.`package`.root()./("tmp")./("diary.txt");
val x$1: Boolean = qual$1.createIfNotExists$default$1();
qual$1.createIfNotExists(x$1)
}.appendNewLine(io.this.Codec.fallbackSystemCodec()).appendLines(scala.this.Predef.wrapRefArray[String](Array[String]{"My name is", "Inigo Montoya"}), io.this.Codec.fallbackSystemCodec());
val x$2: better.files.File = better.files.`package`.home()./("Documents");
val x$3: Boolean = qual$2.moveTo$default$2();
qual$2.moveTo(x$2, x$3)
}.renameTo("princess_diary.txt").changeExtensionTo(".md")."lines" // def lines(codec: scala.io.Codec): Iterator[String] in class File, tree.tpe=(codec: scala.io.Codec)Iterator[String]
Apply( // implicit def fallbackSystemCodec(): scala.io.Codec in trait LowPriorityCodecImplicits, tree.tpe=scala.io.Codec
io.this."Codec"."fallbackSystemCodec" // implicit def fallbackSystemCodec(): scala.io.Codec in trait LowPriorityCodecImplicits, tree.tpe=()scala.io.Codec
Nil
)
)
()
)
)
== Expanded type of tree ==
TypeRef(
TypeSymbol(
final class Array[T] extends Serializable with Cloneable
)
args = List(
TypeRef(
TypeSymbol(
final class String extends Serializable with Comparable[String] with CharSequence
)
)
)
)
uncaught exception during compilation: scala.reflect.internal.Types$TypeError
Error:scalac: Error: bad symbolic reference. A signature in File.class refers to term time
in package java which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling File.class.
scala.reflect.internal.Types$TypeError: bad symbolic reference. A signature in File.class refers to term time
in package java which is not available.
It may be completely missing from the current classpath, or the version on
the classpath might be incompatible with the version used when compiling File.class.
at scala.reflect.internal.pickling.UnPickler$Scan.toTypeError(UnPickler.scala:847)
at scala.reflect.internal.pickling.UnPickler$Scan$LazyTypeRef.complete(UnPickler.scala:854)
at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1231)
at scala.reflect.internal.Symbols$Symbol.tpe(Symbols.scala:1202)
at scala.tools.nsc.transform.SpecializeTypes$$anonfun$specializedTypeVars$5.apply(SpecializeTypes.scala:428)
at scala.tools.nsc.transform.SpecializeTypes$$anonfun$specializedTypeVars$5.apply(SpecializeTypes.scala:428)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractTraversable.map(Traversable.scala:105)
at scala.tools.nsc.transform.SpecializeTypes.specializedTypeVars(SpecializeTypes.scala:428)
at scala.tools.nsc.transform.SpecializeTypes$$anonfun$specializedTypeVars$3.apply(SpecializeTypes.scala:404)
at scala.tools.nsc.transform.SpecializeTypes$$anonfun$specializedTypeVars$3.apply(SpecializeTypes.scala:404)
at scala.reflect.internal.SymbolTable.atPhase(SymbolTable.scala:207)
at scala.reflect.internal.SymbolTable.beforePhase(SymbolTable.scala:215)
at scala.tools.nsc.transform.SpecializeTypes.specializedTypeVars(SpecializeTypes.scala:404)
at scala.tools.nsc.transform.SpecializeTypes.scala$tools$nsc$transform$SpecializeTypes$$specializeMember(SpecializeTypes.scala:898)
at scala.tools.nsc.transform.SpecializeTypes$$anonfun$22$$anonfun$apply$20.apply(SpecializeTypes.scala:752)
at scala.tools.nsc.transform.SpecializeTypes$$anonfun$22$$anonfun$apply$20.apply(SpecializeTypes.scala:751)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:251)
at scala.collection.AbstractTraversable.flatMap(Traversable.scala:105)
at scala.tools.nsc.transform.SpecializeTypes$$anonfun$22.apply(SpecializeTypes.scala:751)
at scala.tools.nsc.transform.SpecializeTypes$$anonfun$22.apply(SpecializeTypes.scala:749)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:251)
at scala.collection.AbstractTraversable.flatMap(Traversable.scala:105)
at scala.tools.nsc.transform.SpecializeTypes.specializeClass(SpecializeTypes.scala:749)
at scala.tools.nsc.transform.SpecializeTypes.transformInfo(SpecializeTypes.scala:1172)
at scala.tools.nsc.transform.InfoTransform$Phase$$anon$1.transform(InfoTransform.scala:38)
at scala.reflect.internal.Symbols$Symbol.rawInfo(Symbols.scala:1321)
at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1241)
at scala.reflect.internal.Symbols$Symbol.isDerivedValueClass(Symbols.scala:658)
at scala.reflect.internal.Symbols$Symbol.isMethodWithExtension(Symbols.scala:661)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.preEraseNormalApply(Erasure.scala:1100)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.preEraseApply(Erasure.scala:1195)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.preErase(Erasure.scala:1205)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1280)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1030)
at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2927)
at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2925)
at scala.collection.immutable.List.loop$1(List.scala:170)
at scala.collection.immutable.List.mapConserve(List.scala:186)
at scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2925)
at scala.reflect.internal.Trees$class.itransform(Trees.scala:1238)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2897)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:48)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1292)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1030)
at scala.reflect.internal.Trees$$anonfun$itransform$2.apply(Trees.scala:1235)
at scala.reflect.internal.Trees$$anonfun$itransform$2.apply(Trees.scala:1233)
at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2936)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:34)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:28)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:19)
at scala.reflect.internal.Trees$class.itransform(Trees.scala:1232)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2897)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:48)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1288)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1030)
at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2927)
at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2925)
at scala.collection.immutable.List.loop$1(List.scala:170)
at scala.collection.immutable.List.mapConserve(List.scala:186)
at scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2925)
at scala.reflect.internal.Trees$class.itransform(Trees.scala:1276)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2897)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.scala$tools$nsc$transform$TypingTransformers$TypingTransformer$$super$transform(TypingTransformers.scala:44)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$1.apply(TypingTransformers.scala:44)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$1.apply(TypingTransformers.scala:44)
at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2936)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:34)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:44)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1292)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1030)
at scala.reflect.api.Trees$Transformer.transformTemplate(Trees.scala:2904)
at scala.reflect.internal.Trees$$anonfun$itransform$4.apply(Trees.scala:1280)
at scala.reflect.internal.Trees$$anonfun$itransform$4.apply(Trees.scala:1279)
at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2936)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:34)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:28)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:19)
at scala.reflect.internal.Trees$class.itransform(Trees.scala:1278)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2897)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:48)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1292)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1030)
at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2927)
at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2925)
at scala.collection.immutable.List.loop$1(List.scala:170)
at scala.collection.immutable.List.mapConserve(List.scala:186)
at scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2925)
at scala.reflect.internal.Trees$$anonfun$itransform$7.apply(Trees.scala:1298)
at scala.reflect.internal.Trees$$anonfun$itransform$7.apply(Trees.scala:1298)
at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2936)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:34)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:28)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:19)
at scala.reflect.internal.Trees$class.itransform(Trees.scala:1297)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:13)
at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2897)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.scala$tools$nsc$transform$TypingTransformers$TypingTransformer$$super$transform(TypingTransformers.scala:44)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$2.apply(TypingTransformers.scala:46)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$2.apply(TypingTransformers.scala:46)
at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2936)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:34)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:46)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$1.transform(Erasure.scala:1292)
at scala.tools.nsc.transform.Erasure$ErasureTransformer.transform(Erasure.scala:1302)
at scala.tools.nsc.transform.Erasure$ErasureTransformer.transform(Erasure.scala:888)
at scala.tools.nsc.ast.Trees$Transformer.transformUnit(Trees.scala:227)
at scala.tools.nsc.transform.Transform$Phase.apply(Transform.scala:30)
at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:464)
at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:431)
at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:431)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:431)
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1583)
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1557)
at scala.tools.nsc.Global$Run.compileSources(Global.scala:1553)
at scala.tools.nsc.Global$Run.compile(Global.scala:1662)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:126)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:102)
at xsbt.CompilerInterface.run(CompilerInterface.scala:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:102)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:48)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
at org.jetbrains.jps.incremental.scala.local.IdeaIncrementalCompiler.compile(IdeaIncrementalCompiler.scala:29)
at org.jetbrains.jps.incremental.scala.local.LocalServer.compile(LocalServer.scala:26)
at org.jetbrains.jps.incremental.scala.remote.Main$.make(Main.scala:62)
at org.jetbrains.jps.incremental.scala.remote.Main$.nailMain(Main.scala:20)
at org.jetbrains.jps.incremental.scala.remote.Main.nailMain(Main.scala)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.martiansoftware.nailgun.NGSession.run(NGSession.java:319)
The utility method autoClosedIterator
can leave the managed resource open. This can happen if the provided function next
throws an exception. The code sample in the ScalaDoc is exactly such an example:
inputStream.autoClosedIterator(_.read())(_ != -1).map(_.toByte)
InputStream.read
can throw an IOException
meaning that the method isOpen
of autoClosedIterator
will not be called afterwards and thus not close the resource in every case.
One possible way to handle this is to wrap Try
around the next
function and adjust the hasNext
accordingly. E.g. for the above example:
inputStream.autoClosedIterator(is => Try(is.read()))(_.getOrElse(-1) != -1).map(_.toByte)
The question is whether this is something the caller or the callee has to deal with.
The readme.md claims that better-files implement a unix-like dsl for file operations. However the current API is not consistent with unix conventions. E.g. when doing
cp(fileA, fileB)
cp
should follow unix conventions in case fileB is a directory, which is to copy a fileA into fileB.
Similar for mv
.
Also hasReadLock and hasWriteLock?
I avoid adding extra repositories in my projects as there is no guarantee that they stay available.
Setting up maven central sync should not be that hard.
See: http://stackoverflow.com/questions/991489/i-cant-delete-a-file-in-java
We may need to set it to writeable before deleting it in Windows
The following examples from the README.md are not working
Seq(file1, file2) >: file3
Seq(file1, file2) >>: file3
cat(file1) >>: file
This is because both operators just allow for String
as input and not for Iterable[File] or Seq[Iterator[Byte]].
There's also a typo in the first example >:
should be BACKTICK>:BACKTICK
Also the File.append* API does not allow for an efficient concatenation of File
s. To do so we need to write something like:
val chunkResults: Iterable[File] = ...
chunkResults.map(_.contentAsString).foreach(combinedFile.appendLines(_))
// or
chunkResults.map(_.bytes.toArray).foreach(combinedBlastOut.append)
Both approaches load the complete input files into memory and don't stream/iterate through them which will cause problems for larger files.
Suggestion:
/**
* Overwrite destination with this file's contents
*
* @param destination
* @return destination
*/
def >(destination: File): File = ???
/**
* Append this file's contents to destination
*
* @param destination
* @return destination
*/
def `>>`(destination: File): File = ???
val dir: files.File = files.File(OssConfig.ossSettings.sharePathMirror) //"src"/"test"
val matches: Files = dir.glob("**/*")
[error] Exception in thread "Thread-4415" java.nio.file.FileSystemException: /memfs/cloudoss1mirror: Too many open files
[error] at sun.nio.fs.UnixException.translateToIOException(UnixException.java:91)
[error] at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
[error] at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
[error] at sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:427)
[error] at java.nio.file.Files.newDirectoryStream(Files.java:457)
[error] at java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:300)
[error] at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:322)
[error] at java.nio.file.FileTreeIterator.(FileTreeIterator.java:72)
[error] at java.nio.file.Files.walk(Files.java:3574)
[error] at java.nio.file.Files.walk(Files.java:3625)
[error] at better.files.package$File.glob(package.scala:200)
[error] at com.sunshinehk.actorfilesystem.ActorFileSystem.checkToDeleteOldFiles(ActorFileSystem.scala:208)
[error] at com.sunshinehk.actorfilesystem.ActorFileSystem$$anon$1.run(ActorFileSystem.scala:183)
Consider adding functionality for calling method file.sibling
directly on File
, i.e.
def sibling(other: String): File = path.resolveSibling(other)
I use this functionality separately of file.renameTo
and have (currently) implemented with an implicit class.
Hi! Project is not dependency free any more. Maybe it's will be good to split project into better-files-core
and better-files-watchers
? Or you can change readme =)
Hi! In 2.14 File("somePath") .glob("**/*.{ext}")
results in empty list, while with 2.13 is OK. Has some semantic changed form 2.13?
BTW, the spec checks globbing with "a" / "b"
only, skipping File("c")
case.
I've tried to work through the great examples from your README.md and all work except for
import better.files._
val testFile = file"test.txt"
"hello" >: testFile
which reports a syntax error:
<console>:1: error: ';' expected but '>:' found.
"hello" >: testFile
I don't see what's wrong with it. Do I need to import some flag to allow for an advanced language feature first?
In contrast
"hello" >>: testFile
works fine, so my general setup seems fine.
I'm working with Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60) and v2.13.0 of better-files.
When you change File.listRecursively
to 'File.recurse' to operate on Stream[File]
, the code becomes more flexible. recurse would return Stream(this) for regular files, Stream(target) for symlinks and a Stream
of the direct contents for a directory. It would be nice if the interface could also handle some state, so it can be limited on the depth and it can could handle circles (symlinks, hard links) by memorizing files it had already processed.
A Stream
would be nice, because so files could be handled as soon as they are found. Interfacing with Akka streams or scalaz-streams should also be easy.
Unfortunately recursion is not so simple as just to flatMap
, especially when handling some state (for depth or for already seen files). Hence I suggest two functions:
recurse(children : File => Stream[File]) : Stream[File]
This function takes a function as a parameter that gives back the children of a file. The user can then provide a function that follows or ingores symlinks and that handles special files (like lnk files on Windows, Aliases on Mac OS X, Gnome's desktop entry files , etc.). Recurse follows all the files recursively.recurseWithState[T, U <# File](initialState : T, children : (T, File) => (T, Stream[U]))
or . Same as bove but additionally provides some state to each call of the child function. This function can use this state to track the depth or to identify already processed files. It can then decide to return an empty stream.You could provide convenience functions for these cases. The latter one would be especially interesting, because it makes the handling of links easier. Perhaps even a combination of the two concepts (depth + already seen files).
Create a better-files-cats which overwrites the side-effecty APIs of Files.scala with monadic ops from cats or IO monad from scalaz
cc: @holgerbrandl
The ignoreIOExceptions
name is not consistent with the given description If this is set to true, an exception is thrown when delete fails
.
The api-docs needs to be improved
There is a small chance of md5 collisions so, don't depend on it for comparing two directory structures
import better.files._
import java.io.{File => JFile}
object Test {
def main(args: Array[String]) = {
val file = file"test.txt"
file.overwrite("hello ")
file.append("world")
assert(file.contentAsString == "hello world\r\n") //ok
assert(file.contentAsString == "hello world") //failed
}
}
Example:
val someFile = File("test.txt")
someFile.write("tt")
for(a<-1 to 10000) {
someFile.lines
}
will die inevitably with a "Too many open files in system" error.
The solution would be to use some closable or even simpler to use Files.readAllLines
instead of Files.lines
See also
http://www.rationaljava.com/2015/02/java-8-pitfall-beware-of-fileslines.html
https://bugs.openjdk.java.net/browse/JDK-8073923
Hi,
I played around with filename functions regarding the extension and saw that hasExtension
(which is used often from other functions) checks for isRegularFile
. In my opinion this is not so good :-) I'd say that these functions operate on names, so even if this “file” is a directory or link, I would expect the file extension concept to apply equally? And as a side effect it checks for file existence, so these functions don't work for non-existing files….
WDYT?
encryption, compression level, passwords etc.
Change to:
file.extension(includeDot: Boolean = true)
e.g. .pdf
vs pdf
Also maybe add another option to return 1 vs all token e.g. what is the extension of foo.scala.html
?
Maybe:
file.extension(includeDot: Boolean = true, includeAll: Boolean = true)
e.g:
setExecutable()
unsetExecutable()
setGroupReadable()
unsetUserWritable()
See also: http://docs.oracle.com/javase/8/docs/api/java/nio/file/AccessMode.html
Sometimes we may generate a large amount of Strings by Iterator[String]
and write them to a File without caching all the generated Strings in memory. Will be great if better-files supports an easy way to do this.
The b-f API is tailored to local files (just check the README) so naturally users will expect better.files.File
instances to render into local filesystem paths (/home/user/test.txt
) instead of URIs (file:///home/user/test.txt
).
For sure there are usecases where URIs have their benefits but the vast majority of users is likely to work with local files only. And as the name suggest better-files a file and not a network api.
It's imho even not really correct to use URI because a relative instance File("my.file")
might not be rooted in a file-system at all (until absolute/full path is queried for it) so it should render as "my.file" and not as "file:///current/working/directory/my.file"
In the latest revisions fullPath has been renamed to pathAsString
which indicates that such a backward-compatibility-breaking change should be possible. :-)
hide()
unhide()
moveToTrash()
restoreFromTrash()
moveToDesktop()
import better.files._
import java.io.{File => JFile}
val f1 = file"test1.txt"
f1 < "hello "
f1 << "world "
f1 << "how are you"
f1 << "?"
println(f1.contentAsString)
/*
should print:
hello world how are you?
but prints:
hello world
how are you
?
*/
Hi, I'm interested in use file monitoring for check file changes in a disk of several TB (2 or 3 TB), do you know how expensive could be in terms of memory/cpu usage??..thank you!..
Hi,
First thank you for your library it makes life working with files much easier :-)
So what would be the recommended way (without converting char to byte) to get bytes from a resource (fetched through resource"/myresource.json") as loadBytes only exist on File class
Thanks
Jakub
See #51
The current implementation of file.list
creates a new DirectoryStream
and returns its Iterator
(mapped to File
s). This means that there is no way for the caller to make sure to close the DirectoryStream
.
A possible solution is to return an iterator that closes the DirectoryStream
automatically after iterating.
Java's Path
is Comparable
: public interface Path extends Comparable<Path>
and can be .sorted
, so here better-files requires a little more code
Ability for user to specify:
http://docs.oracle.com/javase/8/docs/api/java/nio/file/StandardOpenOption.html
http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileVisitOption.html
http://docs.oracle.com/javase/8/docs/api/java/nio/file/LinkOption.html
http://docs.oracle.com/javase/8/docs/api/java/nio/file/StandardCopyOption.html
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.