This is the start of a series of posts on Scala-IO. Scala-IO is as the name implies a library for performing input and output operations with Scala. There are 4 main facets to the library
- Basic IO - Reading and writing to some underlying resource. The current implementation is Java based and thus allows reading and writing to resources like java.io.Readers, Writers, Channels, Streams, etc...
- File API - A library loosely designed after java 7 nio.file API with an additional simple unix like DSL for traversing and searching the filesystem. It is a pluggable architecture which allows plugins for systems like WebDav or Zip filesystems to be addressed in a similar manner as the local filesystem. The included implementation is for the local file system and is implemented on the java.io APIs
- Asynchronous Access - Throughout the APIs are both synchronous and asynchronous options allowing both models of programming to be easily used.
- In the 2.10.x + versions the future implementations are pluggable but require no additional libraries if so that is the desire
- In 2.9.x versions there are two different dependencies one with asynchronous APIs implemented on Akka and one without any asynchronous APIs
- Processor API - An API for defining complex IO processes declaratively.
This series will look at normally a small and simple IO operation each day (or so) rather than only a few in-depth articles. This is required because of my limited available time.
With the introduction done lets look at two small examples:
With the introduction done lets look at two small examples:
Read File with Core API (not File API):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import scalax.io. _ // Create a resource from a file. This is a convenience method and the string can be // a relative path or a absolute path. While this is convenient it is not portable // so it is recommened to use the File API to create a Path object and read from that val input : Input = Resource.fromFile( "someFile" ) // read all bytes into an in memory array input.byteArray // skip first 5 bytes and take the next 5 // force the operation to take place. // The bytes is a ResourceView which is a LongTraversableView, // meaning it will evaluate lazily until the data is forced // or requested input.bytes.drop( 5 ).take( 5 ).force // read all bytes into a string // note: codec can be passed implicitely as well input.string(Codec.UTF 8 ) |
Same thing but with File API:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import scalax.file.Path val path = Path( "file" ) // read all bytes into an in memory array path.byteArray // skip first 5 bytes and take the next 5 // force the operation to take place. // The bytes is a ResourceView which is a LongTraversableView, // meaning it will evaluate lazily until the data is forced // or requested path.bytes.drop( 5 ).take( 5 ).force // read all bytes into a string // note: codec can be passed implicitly as well path.string(Codec.UTF 8 ) |
Oh, man, I love it when a long dormant RSS feed wakes up like this! I'm looking forward to this series.
ReplyDeleteWelcome back! Do you think you will talk about Functional IO too?
ReplyDeleteSee here for example: http://www.stackmob.com/2011/12/scalaz-post-part-2/
A good idea. Will take a bit longer since I will have to research it. It would be a good idea though. While I am familiar with it I have not done a deep dive into it lately.
Delete+1 for "slurpString" =^.^=
ReplyDeletesame, +1 for "slurpString"
ReplyDeleteI am happy you are back. You lessons are very good!
ReplyDeleteReally happy to see this blog live again!
ReplyDeleteNice to see a new post here! This was my favorite scala blog.
ReplyDeleteBeing able to read the whole of a Resource is very handy, but names containing alimentary verbs like "slurp" are pretty unpleasant to me.
ReplyDeleteHonestly I don't have a strong opinion either way. Slurp was the name of the method when I started with the code base and I find it a very descriptive method so I didn't see a strong enough case for changing it. I realized that some people wouldn't love it but that is the case of most anything one does so as long as the intention is clear and the functionality is solid I am not sweating it too much.
ReplyDeleteI'm so happy you are back! This is the most helpful blog for the scala beginner!
ReplyDeleteAnd thanks to you now I'm getting to higher-order kinds and typeclass pattern!
java.io, scala.io, scalax.io...? In .net I have just System.IO.
ReplyDeleteAre you able to orientate me?