[IO]FileA file on the local filesystem.
The class side does the everyday work: create: / append: answer buffered write streams, and delete: / rename:to: / exists?: are one-shot metadata ops. open: answers an [IO]File *value* — a path plus a metadata snapshot — whose byteStream / stringStream open it for reading. Reads and writes park the task, not the scheduler.
var out = [IO]File.create:'/tmp/notes.txt' out.writeAll:'hi'.asBytes out.close ([IO]File.open:'/tmp/notes.txt').stringStream.readAll "* -> 'hi' [IO]File.delete:'/tmp/notes.txt'
One-shot writes, over the buffered streams the native class provides. These are what a script that just wants to save its output should reach for: each opens, writes, and closes, so nothing is left for the exit flush to do. .finally: is the close-on-every-path idiom: the cleanup runs and whatever happened — a value, a throw, a cancellation — propagates unchanged. close flushes.
Like create:, but positioned at the end of an existing file (created if absent) — the log-file mode. Answers the same buffered, flush-on-close ByteStream.
Add text to the end of path (creating it if absent).
A writable ByteStream over a new file at path (an existing file is truncated). Writes are buffered — they accumulate and drain in 16 KiB chunks — and close flushes; a stream never closed is flushed when the program ends. Wrap in .stringStream for text writing.
var out = ([IO]File.create:'/tmp/log.txt').stringStream out.writeln:'first line' out.close [IO]File.delete:'/tmp/log.txt'
Remove the file at path (a missing file throws an IoError). For directories use [IO]Folder.delete:. Returns nil.
Whether anything (file or directory) exists at path. Answers without opening, so it cannot throw for an absent file the way open: does.
An [IO]File over path, reading its metadata now — a missing file throws a catchable IoError (probe with exists?: first to avoid that). Opening holds no file descriptor; byteStream / stringStream open one when reading starts.
The whole file as one String.
Rename (or move) a file. An existing destination is overwritten, as POSIX rename does. Returns nil.
Replace path's contents with text (creating it if absent).
Whether the argument is an [IO]File with the same path string (no canonicalization, so distinct spellings of one file differ). A non-File argument is simply unequal.
Open the file for reading and answer a buffered ByteStream over it — the same stream class a socket yields, so read: / readUntil: / readAll work identically. Each call opens a fresh descriptor; the [IO]File itself is not consumed.
The extension without its dot ('/tmp/notes.txt' → 'txt'), or '' when there is none.
The file's whole path, as the String it was opened with (no canonicalization).
Whether this is a regular file — false for a directory (what an [IO]Folder.next walk uses to tell the two apart). From the metadata snapshot taken when the [IO]File was created.
The file's last-modification time as a Timestamp, from the metadata snapshot taken when the [IO]File was created.
The final path component — the file's name with its extension ('/tmp/notes.txt' → 'notes.txt').
Open the file for positioned reads and answer a RandomAccessFile — readAt:offset count: anywhere in the file, no cursor. What a random-access format (zip) reads through; a fresh fd per call.
The same String as fullpath.
The file's length in bytes, from the metadata snapshot taken when the [IO]File was created — what a tar header (which precedes the content) or a Content-Length needs before reading.
Open the file for reading and answer a text StringStream over it — readLine / eachLine: / readAll are the everyday surface.
var out = [IO]File.create:'/tmp/notes.txt' out.writeAll:'hi'.asBytes out.close ([IO]File.open:'/tmp/notes.txt').stringStream.readAll "* -> 'hi' [IO]File.delete:'/tmp/notes.txt'