;; open the file and loop through the port with read-line: (let ((p (open-input-file file))) (do ((line (read-line p) (read-line p))) ((eof-object? line)) (format #t "~A\n" (string-length line))) (close p)) ;; you can use with-input-from-file to temporarily rebind stdin: (with-input-from-file file (lambda () (do ((line (read-line) (read-line))) ((eof-object? line)) (format #t "~A\n" (string-length line))))) ;; or define a utility procedure to do this (define (for-each-line proc file) (with-input-from-file file (lambda () (do ((line (read-line) (read-line))) ((eof-object? line)) (proc line))))) (for-each-line (lambda (x) (format #t "~A\n" (string-length line))) file) ;; read in the file as a list of lines (define (read-lines file) (let ((ls '())) (with-input-from-file file (lambda () (do ((line (read-line) (read-line))) ((eof-object? line)) (set! ls (cons line ls))) (reverse ls))))) ;; read in the file as a single string (define (file-contents file) (call-with-input-file file (lambda (p) (let* ((size (stat:size (stat p))) (buf (make-string size))) (read-string!/partial buf p) buf)))) ;; use display to print human readable output (display '("One" "two" "three") port) ; (One two three) (display "Baa baa black sheep.\n") ; Sent to default output port ;; use write to print machine readable output (write '("One" "two" "three") port) ; ("One" "two" "three") ;; use (ice-9 rw) to read/write fixed-length blocks of data: (use-modules (ice-9 rw)) (let ((buffer (make-string 4096))) (read-string!/partial buffer port 4096)) ;; truncate-file (truncate-file port length) ; truncate to length (truncate-file port) ; truncate to current pos ;; ftell (define pos (ftell port)) (format #t "I'm ~A bytes from the start of DATAFILE.\n" pos) ;; seek (seek log-port 0 SEEK_END) ; seek to end (seek data-port pos SEEK_SET) ; seek to pos (seek out-port -20 SEEK_CUR) ; seek back 20 bytes ;; block read/write (use-modules (ice-9 rw)) (write-string/partial mystring data-port (string-length mystring)) (read-string!/partial block 256 5) |
(let ((rx (make-regexp "(.*)\\\\$"))) ; or "(.*)\\\\\\s*$" (with-input-from-file file (lambda () (let loop ((line (read-line))) (if (not (eof-object? line)) (let ((m (regexp-exec rx line)) (next (read-line))) (cond ((and m (not (eof-object? next))) (loop (string-append (match:substring m 1) next))) (else ;; else process line here, then recurse (loop next))))))))) |
(do ((line (read-line p) (read-line p)) (i 0 (1+ i))) ((eof-object? line) i)) ;; fastest way if your terminator is a single newline (use-modules (ice-9 rw) (srfi srfi-13)) (let ((buf (make-string (expt 2 16))) (count 0)) (do ((len (read-string!/partial buf p) (read-string!/partial buf p))) ((not len) count) (set! count (+ count (string-count buf #\newline 0 len))))) ;; or use port-line (let loop ((line (read-line p))) (if (eof-object? line) (port-line p) (loop (read-line p)))) |
;; default behaviour of string-tokenize is to split on whitespace: (use-modules (srfi srfi-13)) (let loop ((line (read-line p))) (cond ((not eof-object? line) (for-each some-function-of-word (string-tokenize line)) (loop (read-line p))))) (let ((table (make-hash-table 31))) (let loop ((line (read-line p))) (cond ((not (eof-object? line)) (for-each (lambda (w) (hash-set! table w (1+ (hash-ref table w 0)))) (string-tokenize line)) (loop (read-line p))))) (hash-fold (lambda (k v p) (format #t "~5D ~A\n" v k)) #f table)) |
;; build up the list the reverse it or fold over it: (define lines (read-lines file)) (for-each (lambda (word) do-something-with-word) (reverse lines)) (fold (lambda (word acc) do-something-with-word) #f lines) |
;; save the current position and reseek to it (define (tail file) (call-with-input-file file (lambda (p) (let loop ((line (read-line p))) (cond ((eof-object? line) (sleep sometime) (let ((pos (ftell p))) (seek p 0 SEEK_SET) (seek p pos SEEK_SET))) (else ;; process line )) (loop (read-line p)))))) |
(let ((rand-line #f)) (let loop ((line (read-line p))) (cond ((not (eof-object? line)) (if (= 0 (random (port-line p))) (set! rand-line line)) (loop (read-line p))))) ;; rand-line is the random line ) |
(define (shuffle list) (let ((v (list->vector list))) (do ((i (1- (vector-length v)) (1- i))) ((< i 0) (vector->list v)) (let ((j (random (1+ i)))) (cond ((not (= i j)) (let ((temp (vector-ref v i))) (vector-set! v i (vector-ref v j)) (vector-set! v j temp)))))))) (define rand-lines (shuffle (read-lines file)) |
;; looking for line number desired-line-number (do ((line (read-line p) (read-line p))) ((= ((port-line p) desired-line-number) line))) ;; or read into a list (define lines (read-lines file)) (list-ref lines desired-line-number) ;; @@INCOMPLETE@@ ; (define (build-index data-file index-file) ; ) ; (define (line-with-index data-file index-file line-number) ; ) |
;; use string-tokenize with an appropriate character set (use-modules (srfi srfi-13) (srfi srfi-14)) (define fields (string-tokenize line (string->charset "+-"))) (define fields (string-tokenize line (string->charset ":"))) (define fields (string-tokenize line)) |
(let ((p (open-file file "r+"))) (let ((pos 0)) (let loop ((line (read-line p))) (cond ((eof-object? (peek-char p)) (seek p 0 SEEK_SET) (truncate-file p pos) (close p)) (else (set! pos (ftell p)) (loop (read-line p))))))) |
;; no equivalent - don't know how Guile under windows handles this |
(let* ((address (* recsize recno)) (buf (make-string recsize))) (seek p address SEEK_SET) (read-string!/partial buf p) buf) |
(let* ((address (* recsize recno)) (buf (make-string recsize))) (seek p address SEEK_SET) (read-string!/partial buf p) ;; modify buf, then write back with (seek p address SEEK_SET) (write-string/partial buf p) (close p)) ;; @@INCOMPLETE@@ ;; weekearly |
(seek p addr SEEK_SET) (define str (read-delimited (make-string 1 #\nul) p)) #!/usr/local/bin/guile -s !# ;; bgets -- get a string from an address in a binary file (use-modules (ice-9 format)) (define args (cdr (command-line))) (define file (car args)) (define addrs (map string->number (cdr args))) (define delims (make-string 1 #\nul)) (call-with-input-file file (lambda (p) (for-each (lambda (addr) (seek p addr SEEK_SET) (format #t "~X ~O ~D ~S\n" addr addr addr (read-delimited delims p))) addrs))) ;; @@INCOMPLETE@@ ;; strings |