NAME

Sidef::Types::Glob::FileHandle - File handle object for reading, writing, and managing files.

DESCRIPTION

This class wraps an open Perl filehandle (from a real file, a standard stream, or an in-memory string buffer) and provides methods for reading, writing, positioning, locking, and line/character iteration.

SYNOPSIS

# Open a file and get a FileHandle
var fh = File("/path/to/file.txt").open_r

# Read all content
var content = fh.slurp

# Read line by line
fh.each {|line| say(line) }

# Create an in-memory buffer
var buf = FileHandle.new_buf(:raw, "initial content")
buf.print("more content")

# Standard streams
var stdout = FileHandle.stdout
var stderr = FileHandle.stderr
var stdin  = FileHandle.stdin

INHERITS

Inherits methods from Sidef::Object::Object.

CONSTRUCTION

new

FileHandle(fh, parent=nil)
FileHandle.new(fh, parent=nil)

Wraps a raw filehandle fh (as obtained from opening a File or building a buffer) into a FileHandle object. parent is stored for later retrieval via "parent" -- normally a File object, though this constructor doesn't enforce that. Not typically called directly; use File's own open/open_r/open_w/etc. methods, or "new_buf", instead.

Aliases: call

new_buf

FileHandle.new_buf(mode=:raw, initial_string="")

Creates a new in-memory filehandle backed by a string buffer, seeded with initial_string. In scalar context, returns just the FileHandle; in list context, returns both the FileHandle and the underlying String buffer object (also retrievable afterwards via "parent"). If initial_string is non-empty, the handle's position starts at the end of it (so an immediate .print appends rather than overwriting) -- use "rewind" first if you want to read from the beginning.

var buf = FileHandle.new_buf(:raw, "initial")
buf.print("appended")
say(buf.parent)              #=> "initialappended"

var (fh, str) = FileHandle.new_buf
fh.print("hello")
say(str)                     #=> "hello"

Aliases: new_buffer

stdout

FileHandle.stdout

Returns a FileHandle wrapping the standard output stream.

stderr

FileHandle.stderr

Returns a FileHandle wrapping the standard error stream.

stdin

FileHandle.stdin

Returns a FileHandle wrapping the standard input stream.

INTROSPECTION

get_value

self.get_value

Returns the raw underlying Perl filehandle. A low-level method, mainly useful for interop rather than everyday Sidef code.

parent

self.parent

Returns whatever was passed as the parent argument when the handle was created -- typically the File object it was opened from, or the String buffer object for a handle created with "new_buf".

Aliases: file

is_on_tty

self.is_on_tty

Returns true if the filehandle is connected to a terminal (TTY), false otherwise.

Aliases: isatty

fileno

self.fileno

Returns the numeric file descriptor for the filehandle.

eof

self.eof

Returns true if the filehandle is at end-of-file, false otherwise.

tell

self.tell

Returns the current position of the filehandle, in bytes from the beginning.

stat

self.stat

Returns a Stat object describing the filehandle's current target (works even for a handle with no associated path, such as an in-memory buffer).

lstat

self.lstat

Like "stat". Since the handle is already open (and opening a path always follows any symlink in it), there's no meaningful "don't follow the link" distinction left to make on an already-open handle -- this behaves the same as "stat" here.

CONFIGURATION

autoflush

self.autoflush(bool)

Enables (true) or disables (false) autoflush on the filehandle, so that output is flushed immediately after every write. Returns self.

binmode

self.binmode(encoding)

Applies a PerlIO encoding layer (e.g. ":raw", ":utf8", ":encoding(UTF-8)") to the filehandle. Returns self.

fcntl

self.fcntl(func, flags)

Performs a low-level fcntl operation on the filehandle with the given numeric func and flags. Returns true on success, false otherwise.

lock

self.lock

Applies an exclusive advisory lock (LOCK_EX) to the filehandle. Returns true on success, false otherwise.

unlock

self.unlock

Releases an advisory lock (LOCK_UN) on the filehandle. Returns true on success, false otherwise.

flock

self.flock(mode)

Applies an advisory lock to the filehandle using the given numeric mode (see the Fcntl LOCK_* constants). "lock" and "unlock" are convenience wrappers around this for the two most common modes. Returns true on success, false otherwise.

READING

read

self.read(var_ref, length, offset=nil)

Reads up to length bytes into var_ref (optionally starting at offset within whatever var_ref already held), and returns the number of bytes actually read, as a Number. var_ref is always left holding a String afterwards, even on a short or failed read.

sysread

self.sysread(var_ref, length, offset=nil)

Like "read", but performs a low-level sysread, bypassing buffered I/O.

slurp

self.slurp

Reads and returns the entire remaining content of the filehandle as a single String.

var content = File("data.txt").open_r.slurp

read_line

self.read_line
self.read_line(var_ref)

Reads a single line (with the line terminator removed). With no argument, returns the line as a String, or nil at end-of-file. With var_ref, stores the line through it and returns true, or returns false (leaving var_ref untouched) at end-of-file.

var line = fh.read_line

Aliases: readln, readline, get, line

read_char

self.read_char
self.read_char(var_ref)

Reads a single character. With no argument, returns it as a String, or nil at end-of-file. With var_ref, stores it through the reference and returns true, or returns false at end-of-file.

Aliases: getc, char

read_byte

var byte = fh.read_byte

var value = 0
if (fh.read_byte(\value)) {
    say value
}

Reads a single byte from the file handle and returns its numeric value in the range 0..255.

When called without an argument, the method returns the byte value as a Number. If the end of the file has been reached, it returns nil.

An optional variable-reference may be provided to receive the byte value. In this form, the method returns a Boolean indicating success: true if a byte was read, or false on end-of-file.

This method is equivalent to reading a single character with Perl's getc() and converting it to its numeric byte value using ord().

Examples:

var fh = File("data.bin").open_r

while (var b = fh.read_byte) {
    say b
}

Using the Boolean form:

var fh = File("data.bin").open_r
var byte

while (fh.read_byte(\byte)) {
    say byte
}

Aliases: getb, byte

read_lines

self.read_lines

Reads every remaining line and returns them as an Array of Strings, with line terminators removed.

Aliases: readlines, lines

read_to

self.read_to(var_ref)
self >> var_ref
self » var_ref

Reads a single line (with the line terminator removed) into var_ref, or sets var_ref to nil at end-of-file, and returns self (so it can be chained, unlike "read_line").

fh >> \line
say(line)

Aliases: operator >>, operator »

iter

self.iter

Returns an iterator (a Block) that returns one line at a time (with the line terminator removed) each time it's called with .run, or nil once end-of-file is reached.

var it = fh.iter
while (defined(var line = it.run)) {
    say(line)
}

WRITING

print

self.print(*args)

Writes args to the filehandle with no trailing newline. Returns true on success, false otherwise.

Aliases: write, spurt

println

self.println(*args)

Writes args to the filehandle, followed by a newline. Returns true on success, false otherwise.

Aliases: say

printf

self.printf(format, *args)

Writes formatted output (C-style printf semantics), with no trailing newline. Returns true on success, false otherwise.

fh.printf("%s: %d\n", name, value)

printlnf

self.printlnf(format, *args)

Like "printf", but appends a newline to format first. Returns true on success, false otherwise.

fh.printlnf("%s: %d", name, value)

Aliases: sayf

syswrite

self.syswrite(scalar, length=nil, offset=nil)

Writes scalar to the filehandle using a low-level syswrite, bypassing buffered I/O (optionally only length bytes, starting at offset). Returns true on success, false otherwise.

write_from

self.write_from(*args)
self << args
self « args

Writes args to the filehandle (like "print"), but always returns self regardless of whether the write actually succeeded -- unlike "print", this doesn't report success/failure through its return value.

fh << "some data"

Aliases: operator <<, operator «

BULK LINE AND CHARACTER PROCESSING

The methods below all read the filehandle to exhaustion (there's no early-exit form), so they're only appropriate for a stream that actually ends.

each

self.each(block)

Calls block once per remaining line (terminator removed), and returns self.

fh.each {|line| say(line) }

Aliases: each_line

each_char

self.each_char(block)

Calls block once per remaining character, and returns self.

fh.each_char {|c| print(c) }

grep

self.grep(obj)

Reads every remaining line and returns an Array of just the ones for which obj (typically a Block, or anything else responding to .run) returns a truthy value.

var matches = fh.grep {|line| line.contains("pattern") }

Aliases: select

map

self.map(block)

Reads every remaining line and returns an Array of the results of calling block on each one.

var upper = fh.map {|line| line.uc }

Aliases: collect

words

self.words

Reads every remaining line, splits each on whitespace, and returns a flat Array of every non-empty word (as Strings) across all lines.

chars

self.chars

Reads the entire remaining content and returns an Array of every individual character (as Strings).

POSITIONING AND SIZE

rewind

self.rewind

Repositions the filehandle to the very beginning. Returns true on success, false otherwise.

seek

self.seek(pos, whence)

Repositions the filehandle to pos bytes relative to whence (0 = start, 1 = current position, 2 = end). Returns true on success, false otherwise.

sysseek

self.sysseek(pos, whence)

Like "seek", but performs a low-level sysseek, bypassing buffered I/O.

truncate

self.truncate(length=0)

Truncates the file to length bytes. Returns true on success, false otherwise.

FILE OPERATIONS

close

self.close

Closes the filehandle. Returns true on success, false otherwise.

copy

self.copy(other)

Copies the remaining content of self into other, which must be another FileHandle object (checked with an exact type match, so not even a subclass would be accepted) -- returns nil immediately without copying anything if it isn't. Returns true on success, false on failure.

Aliases: cp

EXAMPLES

Reading a file line by line

var fh = File("large.txt").open_r
fh.each {|line| say(line.trim) }
fh.close

Writing with an explicit handle

var out = File("output.txt").open_w
out.say("Header")
10.times {|i| out.say("Line #{i}") }
out.close

In-memory buffers

var buf = FileHandle.new_buf(:raw, "start:")
buf.print("more")
say(buf.parent)          #=> "start:more"

# Read the buffer back from the beginning
buf.rewind
say(buf.slurp)            #=> "start:more"

Using the >> and << operators

var fh = File("data.txt").open_rw

fh << "first line\n"
fh.rewind

var line = nil
fh >> \line
say(line)                 #=> "first line"

Filtering and transforming lines

var fh = File("access.log").open_r

var errors = fh.grep {|line| line.contains("ERROR") }
say(errors.len)

SEE ALSO

Sidef::Types::Glob::File, Sidef::Types::Glob::Dir, Sidef::Types::String::String