Wednesday, September 26, 2012

Scala-IO Core: To Resource Converters

In order to simplify integration with existing libraries, most commonly Java libraries, Scala-IO provides a JavaConverters object with implicit methods that add as*** methods (asInput, asOutput, asSeekable, etc...) to several types of objects.  It is the same pattern as in the scala.collection.JavaConverters object.

These methods can be used instead of the Resource.from*** methods to provide a slightly nicer appearing code.

There is one warning. When using JavaConverters, instead of Resource.from*** for creating Input/Output/Seekable/etc... objects, the chances of falling into the trap of creating non-reusable resources or causing a resource leak is increased. See: scala-io-core-reusable-resources for more details on this.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// JavaConverters object contains the implicit methods
// which add the as*** methods to the applicable _normal_ objects
import scalax.io.JavaConverters._
 
// Several objects can be converted to input objects using
// asInput.  URLs, File, RandomAccessFile, InputStream, Traversable[Byte]
// Array[Byte], ReadableByteChannel
val input = new URL("http://www.camptocamp.com").asInput
 
// simple demonstation using the newly created input object
println(input.bytes.size)
 
// asSeekable can only be applied to a few objects at the
// moment.  Including RandomAccessFile, SeekableByteChannel,
// File and perhaps in future mutable Sequences
val file = new java.io.File("somefile.txt").asSeekable
 
// demonstrate a seekable method.  This method
// ensures the file is empty
file.truncate(0)
 
// write hi using the Output  API
file.write("hi :)")
 
// output the file to the console to see the results
println(file.string)
 
// asUnmanaged*** created Unmanaged resources for
// operations.  The Unmanaged Resource post will
// discuss this in more detail but essentially the
// resource is not closed and thus is useful when
// dealing with underlying objects that should not
// be closed like System.out
val unmanagedOutput = System.out.asUnmanagedOutput
 
// prints to standard out: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
unmanagedOutput.writeStrings(1 to 10 map (_.toString), ", ")
 
// prints: Hello World
// This demonstrates how a simple Array or Traversable can be easily used
// as an Input object.  The array is Hello world encoded as normal latin1
println(Array(72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100).asInput.string)
 
// prints: Hll Wrld
// Raw Strings and Reader objects cannot currently be converted to an Input object
// but can be converted to ReadChars object (Essentially the character API of Input)
println("Hello World".asReadChars.chars.filterNot(c => "aeiou" contains c) mkString)
 
// Similarly Writer objects cannot be Output objects since they can't write
// bytes so asWriteChars is used to be able to have the string writing
// capabilities of Scala-IO
new java.io.FileWriter("somefile.txt").asWriteChars write "Hi"
 
// prints: Hi
println(new java.io.FileReader("somefile.txt").asReadChars.string)

1 comment: