File
File objects are returned by open and
provide methods for file operations. All operations on closed files raise a
runtime error.
Inherits
Methods
write data
Writes data to the file.
Parameters
| Name | Type | Description |
|---|---|---|
data |
Str|Bin |
Data to write. Strings are written as UTF-8 text. |
Returns
Int (number of bytes written)
Example
open output.txt w do |file|
let bytes_written = file.write "Hello, World!"
echo "Wrote $bytes_written bytes"
# Write binary data
let binary = b"Hello"
file.write binary
set_size size
Truncates the file to the given byte length.
If the file has buffered unread data, the logical cursor position is preserved after truncation.
Parameters
| Name | Type | Description |
|---|---|---|
size |
Int |
New file length in bytes |
Example
lock range :shared? func
Acquires a byte-range lock while func runs.
Parameters:
| Name | Type | Description |
|---|---|---|
range |
Range |
Half-open byte range; .. is total |
shared |
Bool? |
Acquire a shared lock |
func |
Func |
Block receiving a FileLock |
Returns: the block's result
The lock is exclusive unless shared is true. It is released before the
method returns, including when the block raises an error or is canceled.
Release runs with interruption masked and may wait indefinitely.
Locks are mandatory on Windows, where they prevent conflicting file access. On Unix they are advisory and affect only programs that cooperate through file locking.
Native blocking acquisition cannot be canceled. Canceling the strand may
leave a blocking worker waiting for a conflicting lock and delay shutdown.
Use try_lock with async retry for bounded or cancellable waiting.
Overlapping active lock ranges on the same File are unsupported, including
identical shared ranges.
Finite zero-length ranges are invalid on Unix. On Windows they conflict only
with positive-length ranges that start before and end after their offset. They
do not conflict with another zero-length range or a range starting at the same
offset. The zero-length range 0..0 is invalid.
try_lock range :shared? func
Attempts to acquire a byte-range lock without waiting.
Parameters:
| Name | Type | Description |
|---|---|---|
range |
Range |
Half-open byte range; .. is total |
shared |
Bool? |
Acquire a shared lock |
func |
Func |
Block receiving a FileLock |
Returns: the block's result
The block always runs. lock.held is false when another handle holds a
conflicting lock. Other acquisition failures raise errors.
read :size?
Reads data from the file.
Parameters
| Name | Type | Description |
|---|---|---|
size |
Int |
Number of bytes to read. If nil, reads entire file. |
Returns
Str in text mode, binary blob in binary
mode
Example
# Read entire file
open input.txt r do |file|
let content = file.read()
echo "File contents: $content"
# Read specific number of bytes
open data.bin rb do |file|
let header = file.read 4
let rest = file.read()
metadata()
Gets file metadata.
Returns
Fields:
| Field | Type | Description |
|---|---|---|
len |
Int |
File size in bytes |
type |
Sym |
File type: :FILE:, :DIR:, :SYMLINK:, :FIFO:, :CHAR_DEVICE:, :BLOCK_DEVICE:, :SOCKET:, or :UNKNOWN: |
Optional timestamps (platform-dependent):
| Field | Type | Description |
|---|---|---|
modified |
DateTime |
Last modification time |
accessed |
DateTime |
Last access time |
created |
DateTime |
Creation/change time |
Unix-only (these fields do not exist on Windows):
| Field | Type | Description |
|---|---|---|
mode |
Int |
File permissions and type (stat mode) |
dev |
Int |
Device ID |
ino |
Int |
Inode number |
nlink |
Int |
Number of hard links |
uid |
Int |
User ID of owner |
gid |
Int |
Group ID of owner |
rdev |
Int |
Device ID (if special file) |
blksize |
Int |
Preferred block size for I/O |
blocks |
Int |
Number of 512-byte blocks allocated |
Windows-only (these fields do not exist on Unix):
| Field | Type | Description |
|---|---|---|
win_attrs |
Int |
Raw Windows file attribute bitmask |
Example
open data.txt r do |file|
let meta = file.metadata()
echo "Size: $(meta.size)"
echo "Type: $(meta.type)"
echo "Modified: $(meta.modified)"
echo "Modified seconds: $(meta.modified.unix_secs)"
if (sys.os_info().family != :WINDOWS:)
echo "Mode: $(meta.mode)"
echo "Owner: UID=$(meta.uid), GID=$(meta.gid)"
else
echo "Attributes: $(meta.win_attrs)"
fs_metadata()
Gets filesystem metadata for the filesystem backing this open file.
Returns
Example
open data.txt r do |file|
let meta = file.fs_metadata()
echo "Capacity: $(meta.capacity)"
echo "Available: $(meta.available)"
sec_desc :owner = true :group = true :dacl = true :sacl = false
Gets selected parts of the Windows security descriptor through this file's existing handle.
Parameters:
| Name | Type | Description |
|---|---|---|
owner |
Bool |
Load the owner SID |
group |
Bool |
Load the primary group SID |
dacl |
Bool |
Load the discretionary ACL |
sacl |
Bool |
Load the system ACL |
Returns: security.windows.SecDesc
The operation raises a permission error if the file was opened without the
necessary Windows access rights. Other platforms raise UnsupportedError.
set_sec_desc desc
Applies the components selected by a security descriptor's mask through
this file's existing handle.
Parameters:
| Name | Type | Description |
|---|---|---|
desc |
security.windows.SecDesc |
Security descriptor to apply |
The operation raises a permission error if the file was opened without the
necessary Windows access rights. Windows may normalize the resulting
descriptor. Other platforms raise UnsupportedError.
acl :default?
Gets the POSIX.1e ACL stored on the open file.
Parameters:
| Name | Type | Description |
|---|---|---|
default |
Bool? |
Query the directory's inheritable default ACL |
Returns: security.unix.Acl, or nil
set_acl acl :default?
Sets or removes a POSIX.1e ACL on the open file.
Parameters:
| Name | Type | Description |
|---|---|---|
acl |
security.unix.Acl|nil |
ACL to set, or nil to remove it |
default |
Bool? |
Update the directory's inheritable default ACL |
xattrs :namespace?
Lists extended attributes for this file.
On Windows, this uses NTFS extended attributes. Returned names may differ in case from the requested name.
Parameters
| Name | Type | Description |
|---|---|---|
namespace |
Str|Sym? |
Namespace to query; :USER: and :SYSTEM: name well-known namespaces, and :ANY: lists all namespaces |
Returns
iterator of XattrEntry
streams
Lists alternate data streams for this file.
This is only supported on Windows.
Returns
iterator of StreamEntry
let path = Path data.txt
open $path r do |file|
for stream = file.streams()
echo "$(stream.name) $(stream.type)"
echo (path / stream)
xattr name :namespace?
Gets an extended attribute value.
Parameters
| Name | Type | Description |
|---|---|---|
name |
Str|XattrEntry |
Attribute name or entry from xattrs |
namespace |
Str|Sym? |
Namespace to query |
Returns
set_xattr name value :namespace?
Sets an extended attribute value.
On Windows, empty values are rejected. NTFS deletes the attribute instead of storing an empty value.
Parameters
| Name | Type | Description |
|---|---|---|
name |
Str|XattrEntry |
Attribute name or entry from xattrs |
value |
Str|Bin |
Attribute bytes; strings use UTF-8 |
namespace |
Str|Sym? |
Namespace to update |
remove_xattr name :namespace?
Removes an extended attribute.
Parameters
| Name | Type | Description |
|---|---|---|
name |
Str|XattrEntry |
Attribute name or entry from xattrs |
namespace |
Str|Sym? |
Namespace to update |
seek offset
Moves the file cursor by a relative byte offset.
Buffered unread data is discarded before the seek so subsequent reads use the new cursor position.
Parameters
| Name | Type | Description |
|---|---|---|
offset |
Int |
Relative byte offset from current |
Returns
Int - New absolute byte position
Example
seek start: ofs
Moves the file cursor to an absolute byte offset from the start of the file.
Buffered unread data is discarded before the seek so subsequent reads use the new cursor position.
Parameters
| Name | Type | Description |
|---|---|---|
ofs |
Int |
Absolute byte offset from file start |
Returns
Int - New absolute byte position
Example
seek end: ofs
Moves the file cursor to a byte offset relative to the end of the file.
Buffered unread data is discarded before the seek so subsequent reads use the new cursor position.
Parameters
| Name | Type | Description |
|---|---|---|
ofs |
Int |
Byte offset relative to file end |
Returns
Int - New absolute byte position
Example
tell()
Returns the current file cursor position in bytes.
Returns
Example
close()
Explicitly closes the file. Required if you didn't use the func parameter to
open().
Example
Iterator and Sink Protocols
Files implement the iterator and sink protocols, allowing them to be used
with for loops, .next(), .put(), and strand.redirect.
input/output
Returns the file as its own iterator and sink.
Returns
The file object itself
next
Fetches the next item from the file.
Text mode: Reads the next line (delimited by \n), stripping the line
ending. Handles both \n and \r\n line endings.
Binary mode: Reads a chunk of data of arbitrary length.
put
Writes a value to the file.
Text mode:
- If the value is binary data (
Bin), writes it unmodified - Otherwise, converts to string and appends the line ending for the VFS target on which the file handle was opened
Binary mode: Writes bytes directly.