Skip to content

File

An open, buffered file.

Returned by open and Path.open, except with buffer: false, which returns a RawFile.

Reads fetch ahead, and writes are held back until the buffer fills, a read needs the file, or the file is flushed or closed. Every other method sees the file as written: pending writes go out first. A positional write, a lock, set_size and a copy into the file also drop read-ahead, so later reads see the change. A file is not closed when it is garbage collected, so close it to keep its pending writes, or use it from a block that closes it.

A function the file is passed to, such as zip.open, reads and writes through the same buffer, so the file and the function see each other's reads and writes.

Positional reads and writes run concurrently, as on a RawFile, unless the file holds pending writes or a function it was passed to is reading or writing through it. Then the operation takes the file exclusively while it writes them out or waits, and another operation on the file raises ConcurrencyError meanwhile.

A file reads lines and text as well as bytes. Text must be UTF-8, and line endings are not translated.

A file is both an iterator and a sink, so it can be used with for, .next(), .put(), and strand.redirect. It yields lines, including their terminators, so a \r\n file stays \r\n and a final line without one yields a value without one. Use chomp to strip them:

for line = file.chomp()
  echo $line

Passed to a child process as stdin:, stdout:, or stderr:, the child reads or writes from the file's logical position. The file stays open, and when the call returns it is positioned where the child left off, so writing a log around a program keeps its output in order. Don't use the file until the call returns. If the call is interrupted, seek before using the file again.

Inherits from: Iter[Str], BaseFile

Methods

(iter)() -> File

Returns the file as its own iterator.

(next)() -> Str

Reads the next line, as read_line does.

(put) value

Writes a value to the file, verbatim.

A Str or Bin contributes its own bytes and nothing else, and anything else is converted to a string first. No line ending is appended, and none is translated.

Use precrimp to terminate written values, with shell.line_ending() for the target's native ending:

open $path w do |file|
  let lines = file.precrimp()
  lines.put "first"
  lines.put "second"

Parameters

NameTypeDescription
value Value Value to write.

(sink)() -> File

Returns the file as its own sink.

flush()

Writes out pending writes.

lines() -> File

Returns the file as an iterator over its lines.

read_line() -> Str

Reads the next line, including its terminator.

Returns

The line, or "" at the end of the file. Only the last line can lack a terminator.

read_str … -> Str

Reads text.

A character that size would split is left for the next read, unless it is the first, which is read whole.

Parameters

NameTypeDescription
size? Int Number of bytes to read. Without it, reads to the end of the file.

Example

open notes.txt do |file|
  let text = file.read_str()