work-in-progress
Rye file names and file paths are prefixed with %, which is a shorthand for file-uri. %somefile.txt is a shorthand for file://somefile.txt. So we are using methods on file-uri Kind.
Use lg 'file-uri to see all related methods.
; Get file extension (including the dot)
File-ext? %data/file.txt ; returns ".txt"
File-ext? %data/file.temp.png ; returns ".png"
; Get filename with extension
Filename? %path/to/document.pdf ; returns "document.pdf"
; Get filename without extension (stem)
Stem? %path/to/document.pdf ; returns "document"
; Get directory path
Dir? %path/to/document.pdf ; returns "path/to"
; Split path into components
Split %path/to/document.pdf ; returns { "path" "to" "document.pdf" }
; Check if path is absolute
Is-absolute %/home/user/file.txt ; returns true
Is-absolute %relative/path.txt ; returns false
; Check if file exists
Does-exist %data/file.txt ; returns true or false
; Read entire file as string
Read %test.txt
; returns string with full content
; Read file as block of lines
Read\lines %test.txt
; returns block with one string per line
; Read file as bytes
Read\bytes %binary.dat
; returns native bytes object
; Write string to file (creates or overwrites)
Write %output.txt "Hello, World!\n"
; returns the content that was written
For more control, you can work with opened file natives directly. These are of kind file. Use lg 'file to see all related methods.
; Create a new file and write to it
Create %output.txt
|Write "Hello, World!\n"
|Write "Second line\n"
|Close
; Open existing file for reading
Open %data.txt :file
|Read :content
Close file
print content
; Get file information
file: Open %data.txt
info: Stat file
print "File size:" ++ to-string Size? info
file .Close
Rye uses a reader/writer pattern for streaming data. This allows processing large files without loading everything into memory.
; Reader from file-uri
reader: Reader %data.txt
; Reader from file object
Open %data.txt |Reader
; Reader from string (for testing/processing)
reader "some string content"
# Standard input, example from bash
$ echo "Hello world" | rye -do 'stdin |Read\string'
; Writer from file object
; Here we use defer variation that lets us
; set deferred close of native inline
Create %output.txt |defer\ 'Close
|Writer |defer\ 'Close
|Write "some\n"
|Write "data\n"
$ rye -silent -do 'stdout |Write "hello\nawk\n"' | awk '{ print $1 }'
# hello
# awk
; Read all content as string
Reader %data.txt :reader |Read\string
reader .Close
print content
; Copy without loading into memory
Open %source.txt |Copy Create %destination.txt
; Or using reader explicitly
reader: Reader %source.txt
writer: Writer Create %dest.txt
reader .Copy writer
; Open file for appending
Open\append %log.txt |defer\ 'Close
|.Write "New log entry\n"
The tail-file builtin monitors files for new content - useful for log file monitoring:
; Tail a file, following new contenta
tailer: tail-file %app.log true true
; Arguments: path, follow (true), reopen on rotation (true)
; Read lines as they are added
forever {
line: tailer .Read-line
print "New line: " ++ line
}
; Close when done
tailer .Close
; Prompt user for input
name: input "Enter your name: "
print "Hello, " ++ name