NAME

Sidef::Types::Glob::File - File manipulation and information retrieval

DESCRIPTION

The File class provides a comprehensive interface for file operations in Sidef, including reading, writing, metadata retrieval, and file system manipulation. It inherits string manipulation capabilities and adds file-specific functionality.

SYNOPSIS

var file = File("example.txt")

# Create and write to a file
file.write("Hello, World!")

# Read file contents
say file.read

# Check file properties
if (file.exists && file.is_readable) {
    say "File exists and is readable"
}

# Get file information
say "Size: #{file.size} bytes"
say "Directory: #{file.dir}"
say "Basename: #{file.base}"

# Copy and move files
file.copy("backup.txt")
file.move("new_location.txt")

# Work with paths
var abs_path = file.abs_path
say "Absolute path: #{abs_path}"

INHERITS

Inherits methods from:

* Sidef::Types::String::String

METHODS

abs

file.abs(base)

Returns the absolute pathname of the file. If base is provided, it is used as the base directory for relative path resolution. Otherwise, the current working directory is used.

var file = File("docs/readme.txt")
say file.abs                    # /home/user/docs/readme.txt
say file.abs("/var/www")        # /var/www/docs/readme.txt

Aliases: abs_name, absname, rel2abs

abs_path

file.abs_path

Returns the canonicalized absolute pathname by resolving all symbolic links and relative path components (. and ..). This is the real, physical path to the file on the filesystem.

var file = File("../project/link_to_file")
say file.abs_path               # /home/user/project/actual_file

Aliases: realpath

access_time_days_diff

file.access_time_days_diff

Returns the number of days since the file was last accessed, relative to the current time. The access time (atime) is updated when the file is read.

var file = File("log.txt")
say "Last accessed #{file.access_time_days_diff} days ago"

append

file.append(string, mode=':utf8')

Appends the given string to the file. If the file doesn't exist, it will be created. The optional mode parameter specifies the encoding layer (default is UTF-8).

var file = File("log.txt")
file.append("New log entry\n")
file.append("Binary data", ':raw')

Returns the File object for method chaining.

base

file.base

Returns the basename of the file (the filename without the directory path), similar to the Unix shell command basename.

var file = File("/home/user/document.txt")
say file.base                   # document.txt

Aliases: base_name, basename

change_time_days_diff

file.change_time_days_diff

Returns the number of days since the file's inode change time (ctime), relative to the current time. The change time is updated when file metadata (permissions, ownership, etc.) or content changes.

var file = File("config.ini")
say "Last changed #{file.change_time_days_diff} days ago"

chmod

file.chmod(permission)

Changes the file's permission bits. The permission can be specified as an octal number or a string.

var file = File("script.sh")
file.chmod(0755)                # rwxr-xr-x
file.chmod("644")               # rw-r--r--

Returns true on success, false otherwise.

chown

file.chown(uid, gid)

Changes the owner and group of the file. Both uid (user ID) and gid (group ID) must be provided as numeric values.

var file = File("data.txt")
file.chown(1000, 1000)          # Change owner and group

Returns true on success, false otherwise. May require elevated privileges.

compare

file.compare(other_file)

Compares the contents of two files byte-by-byte. Returns 0 if files are identical, -1 if the first file is less than the second, 1 if greater, or nil on error.

var file1 = File("original.txt")
var file2 = File("copy.txt")

given (file1.compare(file2)) {
    when (0)  { say "Files are identical" }
    when (-1) { say "file1 < file2" }
    when (1)  { say "file1 > file2" }
    default   { say "Error comparing files" }
}

cp

file.cp(destination)

Copies the file to the specified destination. The destination can be either a filename or a File object. If the destination is a directory, the file is copied into that directory with the same basename.

var file = File("source.txt")
file.cp("backup.txt")           # Copy to backup.txt
file.cp(Dir("backups"))         # Copy into backups directory

Returns true on success, false otherwise.

Aliases: copy

delete

file.delete

Deletes the file from the filesystem and returns true on success, false otherwise. This method will not attempt to delete directories; use Dir.remove for directories instead.

var file = File("temporary.txt")
file.delete && say "File deleted successfully"

Aliases: remove

dir

file.dir

Returns the directory portion of the filename as a String, similar to the Unix shell command dirname. This is the parent directory containing the file.

var file = File("/home/user/documents/file.txt")
say file.dir                    # /home/user/documents

Aliases: dir_name, dirname

dump

file.dump

Returns a String representation of the File object, suitable for debugging. The representation includes the class name and the file path.

var file = File("example.txt")
say file.dump                   # File("example.txt")

edit

file.edit(code)

Reads the file's contents, passes them to the provided code block, and writes the result back to the file. This is useful for in-place file editing.

var file = File("config.txt")
file.edit { |content|
    content.gsub(/old/, 'new')
}

Returns the File object for method chaining.

exists

file.exists

Returns true if the file exists on the filesystem, false otherwise. This checks for existence of any filesystem entity at the path, including regular files, directories, symlinks, etc.

var file = File("data.txt")
file.exists || die "File not found"

has_setgid_bit

file.has_setgid_bit

Returns true if the file has the setgid (set group ID) bit set in its permissions. When set on an executable, the process runs with the group privileges of the file rather than the user.

var file = File("/usr/bin/wall")
file.has_setgid_bit && say "Has setgid bit"

has_setuid_bit

file.has_setuid_bit

Returns true if the file has the setuid (set user ID) bit set in its permissions. When set on an executable, the process runs with the user privileges of the file owner rather than the executor.

var file = File("/usr/bin/sudo")
file.has_setuid_bit && say "Has setuid bit"

has_sticky_bit

file.has_sticky_bit

Returns true if the file has the sticky bit set in its permissions. On directories, this restricts deletion of files to their owners. On some systems, this affects executables in memory.

var dir = File("/tmp")
dir.has_sticky_bit && say "Has sticky bit"

is_abs

file.is_abs

Returns true if the file path is absolute (starts from the root directory), false if it's relative.

File("/home/user/file.txt").is_abs    # true
File("relative/path.txt").is_abs      # false

Aliases: is_absolute

is_binary

file.is_binary

Returns true if the file appears to be a binary file based on heuristic analysis of its contents. This checks for non-text characters in the file's initial bytes.

var file = File("image.png")
file.is_binary && say "Binary file detected"

is_block

file.is_block

Returns true if the file is a block special file (block device), such as a disk partition.

var device = File("/dev/sda1")
device.is_block && say "Block device"

is_char_device

file.is_char_device

Returns true if the file is a character special file (character device), such as a terminal or serial port.

var terminal = File("/dev/tty")
terminal.is_char_device && say "Character device"

is_dir

file.is_dir

Returns true if the file is a directory, false otherwise.

var path = File("/home/user")
path.is_dir && say "This is a directory"

Aliases: is_directory

is_empty

file.is_empty

Returns true if the file has zero size (i.e., is empty), false otherwise.

var file = File("empty.txt")
file.is_empty && say "File is empty"

is_executable

file.is_executable

Returns true if the file is executable by the effective user ID and group ID of the current process.

var script = File("run.sh")
script.is_executable || die "Script is not executable"

is_file

file.is_file

Returns true if the file is a plain (regular) file, as opposed to a directory, symlink, or special file.

var file = File("document.txt")
file.is_file && say "Regular file"
file.is_link

Returns true if the file is a symbolic link. Returns false if symbolic links aren't supported by the filesystem.

var link = File("shortcut")
link.is_link && say "This is a symlink"

is_owned

file.is_owned

Returns true if the file is owned by the effective user ID of the current process.

var file = File("myfile.txt")
file.is_owned && say "You own this file"

is_readable

file.is_readable

Returns true if the file is readable by the effective user ID and group ID of the current process.

var file = File("data.txt")
file.is_readable || die "Cannot read file"

is_real_executable

file.is_real_executable

Returns true if the file is executable by the real user ID and group ID of the current process (not the effective IDs).

var script = File("check.sh")
script.is_real_executable && say "Really executable"

is_real_owned

file.is_real_owned

Returns true if the file is owned by the real user ID of the current process (not the effective UID).

var file = File("data.txt")
file.is_real_owned && say "Really owned by you"

is_real_readable

file.is_real_readable

Returns true if the file is readable by the real user ID and group ID of the current process (not the effective IDs).

var file = File("protected.txt")
file.is_real_readable || say "Not readable with real UID"

is_real_writeable

file.is_real_writeable

Returns true if the file is writable by the real user ID and group ID of the current process (not the effective IDs).

var file = File("data.txt")
file.is_real_writeable && say "Really writable"

is_socket

file.is_socket

Returns true if the file is a Unix domain socket.

var sock = File("/var/run/socket")
sock.is_socket && say "This is a socket"

is_text

file.is_text

Returns true if the file appears to be an ASCII or UTF-8 text file based on heuristic analysis of its contents.

var file = File("readme.txt")
file.is_text && say "Text file detected"

is_writeable

file.is_writeable

Returns true if the file is writable by the effective user ID and group ID of the current process.

var file = File("output.log")
file.is_writeable || die "Cannot write to file"
oldfile.link(newfile)

Creates a hard link from newfile to oldfile. Both names will point to the same inode on the filesystem. Changes to either file affect both names.

var original = File("source.txt")
original.link("hardlink.txt")

Returns true on success, false otherwise.

lstat

file.lstat

Returns a Stat object containing information about the file. Unlike stat, if the file is a symbolic link, lstat returns information about the link itself rather than the target file.

var link = File("symlink")
var info = link.lstat
say "Link size: #{info.size}"

make

file.make(*args)

Creates an empty file if it doesn't exist, or updates the modification and access times if it does exist (like the Unix touch command). Optional arguments can specify permissions or other creation parameters.

var file = File("newfile.txt")
file.make                       # Create empty file
file.make(0644)                 # Create with specific permissions

Returns true on success, false otherwise.

Aliases: touch, create, mkfile

md5

file.md5

Computes and returns the MD5 hash digest of the file's contents as a hexadecimal string.

var file = File("data.bin")
var hash = file.md5
say "MD5: #{hash}"              # MD5: 5d41402abc4b2a76b9719d911017c592

mktemp

File.mktemp(template => "tempXXXXXX", dir => "/tmp")

Creates a temporary file with a unique name based on the provided template. The template should contain a sequence of X characters that will be replaced with random characters. Returns a File object for the created temporary file.

var tmpfile = File.mktemp
tmpfile.write("temporary data")

var custom = File.mktemp(template => "myapp_XXXX", dir => "/var/tmp")

Aliases: make_tmp, make_temp

modification_time_days_diff

file.modification_time_days_diff

Returns the number of days since the file was last modified (content changed), relative to the current time.

var file = File("document.txt")
say "Last modified #{file.modification_time_days_diff} days ago"

mv

file.mv(destination)

Moves (renames) the file to the specified destination. The destination can be either a filename or a File object. If the destination is a directory, the file is moved into that directory with the same basename.

var file = File("old_name.txt")
file.mv("new_name.txt")         # Rename file
file.mv(Dir("archive"))         # Move to archive directory

Returns true on success, false otherwise.

Aliases: move

name

file.name

Returns the complete pathname of the file as a String.

var file = File("/home/user/file.txt")
say file.name                   # /home/user/file.txt

new

File.new(path)

Creates a new File object for the specified path. This is the constructor method, typically called implicitly when using File(path) syntax.

var file = File.new("/path/to/file.txt")
# Equivalent to:
var file = File("/path/to/file.txt")

Aliases: call

open

file.open(mode, fh_ref, err_ref)

Opens the file with the specified mode and stores the filehandle reference in fh_ref. If an error occurs, the error message is stored in err_ref. Common modes include:

'<'  - read
'>'  - write (truncate)
'>>' - append
'+<' - read/write

var file = File("data.txt")
var fh = nil
var err = nil

if (file.open('<', \fh, \err)) {
    # Read from fh
    fh.close
} else {
    die err
}

Returns true on success, false otherwise.

open_a

file.open_a(*args)

Opens the file in append mode and returns a filehandle. If the file doesn't exist, it will be created.

var file = File("log.txt")
var fh = file.open_a
fh.say("Log entry")
fh.close

Aliases: open_append

open_arw

file.open_arw(*args)

Opens the file in append-read-write mode and returns a filehandle. This allows reading the entire file and appending to it.

var file = File("data.txt")
var fh = file.open_arw
# Can read and append
fh.close

Aliases: open_append_read_write

opendir

dir.opendir(*args)

Opens a directory and returns a dirhandle for reading directory entries. This is typically used with directory paths.

var dir = File("/home/user")
var dh = dir.opendir
dh.each { |entry| say entry }
dh.close

open_r

file.open_r(*args)

Opens the file in read-only mode and returns a filehandle.

var file = File("input.txt")
var fh = file.open_r
var content = fh.slurp
fh.close

Aliases: open_read

open_rw

file.open_rw(*args)

Opens the file in read-write mode and returns a filehandle. The file must already exist.

var file = File("data.txt")
var fh = file.open_rw
# Can read and write
fh.close

Aliases: open_read_write

open_w

file.open_w(*args)

Opens the file in write mode (truncating if it exists) and returns a filehandle.

var file = File("output.txt")
var fh = file.open_w
fh.say("Hello, World!")
fh.close

Aliases: open_write

read

file.read(mode=':utf8')

Reads and returns the entire contents of the file as a String. The optional mode parameter specifies the encoding layer (default is UTF-8).

var file = File("data.txt")
var content = file.read          # Read as UTF-8 text
var binary = file.read(':raw')   # Read as raw bytes
link.read_link

Reads and returns the target path of a symbolic link. If the file is not a symbolic link, returns nil.

var link = File("shortcut")
var target = link.read_link
say "Link points to: #{target}"

Aliases: readlink

rel

file.rel(base=Dir.cwd)

Returns the relative pathname of the file with respect to the base directory. If no base is provided, the current working directory is used.

var file = File("/home/user/docs/file.txt")
say file.rel("/home/user")      # docs/file.txt
say file.rel                     # relative to current directory

Aliases: abs2rel, rel_name, relname

rename

file.rename(new_name)

Renames the file to the specified new name. This is a lower-level operation than mv and works within the same filesystem.

var file = File("old.txt")
file.rename("new.txt")

Returns true on success, false otherwise.

sha1

file.sha1

Computes and returns the SHA-1 hash digest of the file's contents as a hexadecimal string.

var file = File("data.bin")
var hash = file.sha1
say "SHA-1: #{hash}"

sha256

file.sha256

Computes and returns the SHA-256 hash digest of the file's contents as a hexadecimal string.

var file = File("data.bin")
var hash = file.sha256
say "SHA-256: #{hash}"

sha512

file.sha512

Computes and returns the SHA-512 hash digest of the file's contents as a hexadecimal string.

var file = File("data.bin")
var hash = file.sha512
say "SHA-512: #{hash}"

size

file.size

Returns the size of the file in bytes. Returns 0 for empty files or if the file doesn't exist.

var file = File("document.txt")
say "File size: #{file.size} bytes"

split

file.split

Splits the file path into its constituent parts and returns them as an Array. This typically includes the volume (on Windows), directory components, and filename.

var file = File("/home/user/docs/file.txt")
var parts = file.split
# ['', 'home', 'user', 'docs', 'file.txt']

splitpath

file.splitpath

Splits the file path into volume, directory, and filename components. Returns an Array with three elements: [volume, directory, filename].

var file = File("/home/user/file.txt")
var (vol, dir, name) = file.splitpath...
# vol: '', dir: '/home/user/', name: 'file.txt'

stat

file.stat

Returns a Stat object containing detailed information about the file, including size, permissions, timestamps, inode number, and more. If the file is a symbolic link, returns information about the target file (use lstat for link info).

var file = File("data.txt")
var info = file.stat
say "Size: #{info.size}"
say "Mode: #{info.mode}"
say "Mtime: #{info.mtime}"
target.symlink(link_name)

Creates a symbolic link named link_name that points to target. The target doesn't need to exist at the time of creation.

var target = File("original.txt")
target.symlink("link_to_original")

Returns true on success, false otherwise.

sysopen

file.sysopen(var_ref, mode, perm)

Opens the file using low-level system call interface with specified mode and permissions. The filehandle is stored in the reference var_ref. Mode flags are numeric (e.g., O_RDONLY, O_WRONLY, O_RDWR).

var file = File("data.bin")
var fh = nil
file.sysopen(\fh, O_RDWR | O_CREAT, 0644)

Returns true on success, false otherwise.

to_file

file.to_file

Returns the File object itself. This is useful for polymorphic code that might receive either a String or File object.

var obj = File("test.txt")
var file = obj.to_file           # Returns same File object

to_s

file.to_s

Returns the file path as a String.

var file = File("/home/user/file.txt")
say file.to_s                    # /home/user/file.txt

Aliases: to_str

truncate

file.truncate(length)

Truncates the file to the specified length in bytes. If the file is larger than length, the extra data is lost. If shorter, it is extended with null bytes.

var file = File("data.txt")
file.truncate(100)               # Truncate to 100 bytes

Returns true on success, false otherwise.

file.unlink(*args)

Deletes one or more files. If called without arguments, deletes the file object itself. If called with arguments, deletes the specified files.

var file = File("temp.txt")
file.unlink                      # Delete this file

File.unlink("file1.txt", "file2.txt")  # Delete multiple files

Returns the number of files successfully deleted.

utime

file.utime(atime, mtime)

Sets the access time and modification time of the file. Times are specified as Unix timestamps (seconds since epoch).

var file = File("data.txt")
var now = Time.now.to_i
file.utime(now, now)             # Update both times to now

Returns true on success, false otherwise.

write

file.write(string, mode=':utf8')

Writes the given string to the file, replacing any existing content. If the file doesn't exist, it will be created. The optional mode parameter specifies the encoding layer (default is UTF-8).

var file = File("output.txt")
file.write("Hello, World!")
file.write(binary_data, ':raw')

Returns the File object for method chaining.

EXAMPLES

Basic File Operations

# Create a file and write content
var file = File("example.txt")
file.write("Line 1\nLine 2\nLine 3\n")

# Read and print contents
say file.read

# Append more content
file.append("Line 4\n")

# Check file properties
say "Size: #{file.size} bytes"
say "Readable: #{file.is_readable}"
say "Writable: #{file.is_writeable}"

File Information and Metadata

var file = File("/etc/passwd")

# Get path components
say "Directory: #{file.dir}"
say "Basename: #{file.base}"
say "Absolute path: #{file.abs_path}"

# Get file statistics
var stat = file.stat
say "Inode: #{stat.ino}"
say "Permissions: #{stat.mode.as_oct}"
say "Owner UID: #{stat.uid}"

# Check age
say "Modified #{file.modification_time_days_diff} days ago"

Working with Checksums

var file = File("download.iso")

# Compute various hash digests
say "MD5:    #{file.md5}"
say "SHA1:   #{file.sha1}"
say "SHA256: #{file.sha256}"
say "SHA512: #{file.sha512}"

File Copying and Moving

var source = File("original.txt")

# Create a backup copy
source.copy("backup.txt")

# Move to archive directory
source.move("archive/original.txt")

# Create hard and symbolic links
File("data.txt").link("hardlink.txt")
File("data.txt").symlink("symlink.txt")

In-Place File Editing

# Convert file to uppercase
File("text.txt").edit { |content|
    content.uc
}

# Replace all occurrences of a pattern
File("config.ini").edit { |content|
    content.gsub(/old_value/, 'new_value')
}

# Process line by line
File("data.csv").edit { |content|
    content.lines.map { |line|
        line.split(',').map { .trim }.join(',')
    }.join("\n")
}

Working with File Handles

# Read line by line
var file = File("large.txt")
var fh = file.open_r
fh.each_line { |line|
    say line.trim
}
fh.close

# Write with explicit handle
var output = File("output.txt")
var fh = output.open_w
fh.say("Header")
10.times { |i|
    fh.say("Line #{i}")
}
fh.close

Temporary Files

# Create a temporary file
var tmp = File.mktemp
tmp.write("temporary data")

# Use custom template
var tmp2 = File.mktemp(
    template => "myapp_XXXXXX",
    dir => "/var/tmp"
)

# Cleanup
tmp.delete
tmp2.delete

File Type Checking

var path = File(ARGV[0])

given (path) {
    when { .is_file }      { say "Regular file" }
    when { .is_dir }       { say "Directory" }
    when { .is_link }      { say "Symbolic link → #{.read_link}" }
    when { .is_socket }    { say "Unix socket" }
    when { .is_block }     { say "Block device" }
    default                { say "Unknown file type" }
}

# Check content type
if (path.is_file) {
    path.is_text   && say "Text file"
    path.is_binary && say "Binary file"
}

SEE ALSO

Sidef::Types::Glob::Dir, Sidef::Types::Glob::FileHandle, Sidef::Types::String::String