Scala File I/O Types of files There are two kinds of files: Text files, and binary files Of course, it’s not that simple… Text files Text files are “human readable,” which really means that a lot of different programs can understand them ASCII (American Standard Code for Information Interchange) has been in widespread use since about 1967 Unicode was designed to support “all” the world’s languages, and began to be used in about 1987 UTF-8 (UCS Transformation Format—8-bit) combines ASCII and Unicode, and has become the Web standard Binary files ASCII is a set of 128 character, many of which are “control” characters Binary files are not designed to be human readable, and are often ad hoc Some familiar binary file types are jpg, gif, png, doc, rtf, class We’ll only be concerned with text files 2 How to refer to a file There are four ways to tell the computer where to find a file (for reading) or put a file (for writing) Provide the absolute path to the file Provide a relative path to the file (starting from the location in which the program is running) This is not too bad, if you provide a complete directory containing both the program and its data It does require the instructor to start the program from the same place you do Tell the operating system to keep the file in a special hidden location For those of you on Windows, this usually means starting with C: This is almost always a terrible idea! It means that anyone you give your program to (like, the instructor) must have the exact same directory structure as you do This is good for default settings, but not for data Ask the user where the file is (often the best approach) 3 How to ask the user Do this: import scala.io.Source, scala.io.Source._, scala.swing.FileChooser If you want to read in a file: val chooser = new FileChooser val response = chooser.showOpenDialog(null) (User selects a file) if (response == FileChooser.Result.Approve) { read in file } If you want to write out a file: val chooser = new FileChooser val response = chooser.showSaveDialog(null) (User selects a file) if (response == FileChooser.Result.Approve) { write out file } 4 Which file was chosen? The result of calling FileChooser is either FileChooser.Result.Approve, or it’s something else If it’s Approve, you can ask it which file was chosen with chooser.selectedFile 5 Accessing files by path import java.io.File val file = new File("C:/Programming/p1.txt") This gives you a file object that represents a file There is no guarantee that there is such a file All the world, except Microsoft, uses forward slashes (/) as path delimiters Microsoft standard is backslashes, \ In a string, backslashes must be doubled: ("C:\\Programming\\p1.txt") Microsoft has ”seen the light” and now allows forward slashes All the world, except Microsoft, uses case-sensitive file names Your TAs aren’t using Windows 6 Reading from a file Either Source.fromFile(file) or Source.fromFile(filename) will give you an iterator for the file The iterator will give you one character at a time Thus, for (ch <- Source.fromFile(file)) { print } will print out the entire file, one character at a time Newlines are included (ch <- Source.fromFile(file).getLines) { print } will print out the entire file, one line at a time Newlines are discarded 7 Putting it all together scala> import scala.io.Source, scala.io.Source._ import scala.io.Source import scala.io.Source._ scala> import scala.swing.FileChooser, java.io.File import scala.swing.FileChooser import java.io.File scala> val chooser = new FileChooser chooser: scala.swing.FileChooser = scala.swing.FileChooser@516331f scala> val response = chooser.showOpenDialog(null) response: scala.swing.FileChooser.Result.Value = Approve scala> if (response == FileChooser.Result.Approve) { | for (line <- Source.fromFile(chooser.selectedFile).getLines) { | println("Processing line: " + line) | } | } 8 The End 9