Walnut/Ordinary Programming/InputOutput

I/O
E file objects are created with the  expression (which produces a "tamed" Java File Object, i.e., a File object that follows capability security discipline). If the word "file" is replaced with a single letter like "c", the letter is assumed to be the drive letter on a Windows machine. This form can only be used when the file name is known literally, and contains only valid URI characters.

If the file name is calculated, i.e., contained in a variable or retrieved with a function call, or if it contains invalid URI characters like space, you must use the calculated name to index into a parent directory or the file system itself. The file system is represented by the expression.

def file1 :=  def file2 :=  def filePath := "c:\\docs\\myFile.txt" def file3 := [filePath] def file4 :=  def file5 :=  def file6 := 
 * 1) E sample
 * 2) File objects for hardwired files:
 * 1) Using a variable for a file name:
 * 1) Using a single character to specify a Windows drive

Note that in the file5 example, we used slashes, not backslashes, to separate directories on a Windows drive. In E'', the slash always works as a directory separator no matter the underlying operating system. ''

When constructing the filePath string we used double backslashes because in strings the backslash must be escaped by a backslash. A double backslash was not required in the hardwired file (file6).

File objects can represent directories as well as simple files. Files inside the directory can be accessed by indexing using square brackets:

def dir :=  def file6 := dir["myFile.txt"]
 * 1) E syntax

Both text files and directories work in conjunction with the "for" loop. With a directory, the loop iterates through the files in the directory. With a text file, the loop iterates through the lines of the file; each line-object is terminated with a newline ('\n') character. The lines in the loop are terminated with newline regardless of the underlying operating system, regardless of the operating system's end-of-line designation.

Files respond to the following messages (see the Edoc for a complete list).


 * exists -- returns true if the file exists
 * deepReadOnly -- returns a file object that can be read, but not written. If the file is a directory, the readOnly nature is transitive to all files and directories reached via this object.
 * setText(textString) -- creates the file and/or replaces the file contents with the text. When written out, the end-of-line designator is automatically converted to the local end-of-line mark for the underlying operating system. On Windows, for example, each line is automatically terminated by a cr/lf pair.
 * getText -- returns the text from the file. Regardless of underlying operating system, the returned text uses a single newline character as the end-of-line mark.
 * getBytes -- returns the bytes of the file in a byte ConstList
 * setBytes(byteList)

stdout and stderr are both TextWriters in the E environment.

Example: recursing through a directory tree searching for a file
def findFile(targetFileName, dir) :void { def iterator(filename, file) { if (filename == targetFileName) { println(`Found $targetFileName at ${file.getPath}`) }        if (file.isDirectory) { findFile(targetFileName, file) }    }     dir.iterate(iterator) } def ehomeDir := [interp.getProps["e.home"]] findFile("Substituter.class", ehomeDir)