Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it better to use import scala.reflect.io.File or java.io.File in Scala?

Tags:

file

scala

I see the scala.reflect.io.File class, is this supposed to help with file operations? Am I supposed to prefer to use this rather than java.io.File? What is the purpose of this class?

like image 859
Phil Avatar asked Nov 22 '13 16:11

Phil


2 Answers

Neither, you're supposed to use java.nio.file, of course.

If you want to "enhance" that API with fancy operators, use extension methods. The author of that code has said as much on the mailing list. Being stuck on Java 6 is considered unfortunate.

The package you're pointing to was pulled into the scala-reflect.jar to support reflection, but warnings are everywhere about its unsupported status.

The AbstractFile abstraction is used by Position, which has a source file. The "file" you get from that is a java.io.File, but AbstractFile has factory methods that take the reflect.io.Path abstraction (with File and Directory subtypes). So all that code remains packaged together.

I have to stop and think every time AbstractFile and File cross my path (pun alert). I used to have a purple "AbstractFile is, like, totally different from File" t-shirt, but it wore out with multiple washings.

On the back it said, "Position has nothing to do with io.Position."

Here is the warning as it touches api.Position, where of course it is user-facing in the scaladoc; notice it says it is a "Java file":

  /** Java file corresponding to the source file of this position.
   *
   *  The return type is `scala.reflect.io.AbstractFile`, which belongs to an experimental part of Scala reflection.
   *  It should not be used unless you know what you are doing. In subsequent releases, this API will be refined
   *  and exposed as a part of scala.reflect.api.
   *
   *  @group Common
   */
  def source: scala.reflect.internal.util.SourceFile

To answer your first question, I think it's safe to say, Yes, it was supposed to help.

like image 112
som-snytt Avatar answered Sep 19 '22 16:09

som-snytt


You shouldn't use scala.reflect.io package for two reasons:

  • it's intended for internal use of reflection code (e.g. is hidden from scala doc)
  • This is library is considered experimental and should not be used unless you know what you are doing.

Here's the standard api provided for file access: scala.io.Source (companion Object, not Class)

import scala.io.Source

val source = Source.fromFile(fileNameString)("UTF-8")
// returns collection.Iterator[String]:
val lines = source.getLines()
// Now do something with lines ...
source.close()

java.nio features Channels and ByteBuffers: reads/writes occur via active background threads which are implicitly managed by the JVM. It's used for high performance (often high-volume) non-blocking I/O, not simple I/O. It reads in in chunks from a channel into buffers and requires the buffer to be parsed and processed.

java.io features Readers and Writers for reading/writing characters with internal encoding/decoding from text files and other sources. These provide some operations beyond Scala's Source object - hence, use these directly if you wish to do advanced operations not supported by Source. It also features InputStreams and OutputStreams for reading/writing raw data bytes from data files, sockets and other data sources.

like image 35
Glen Best Avatar answered Sep 20 '22 16:09

Glen Best