13.2 Byte and String Input
procedure
(read-char [in]) → (or/c char? eof-object?)
in : input-port? = (current-input-port)
> (let ([ip (open-input-string "S2")]) (print (read-char ip)) (newline) (print (read-char ip)) (newline) (print (read-char ip)))
#\S
#\2
#<eof>
> (let ([ip (open-input-bytes #"\316\273")]) ; The byte string contains UTF-8-encoded content: (print (read-char ip))) #\λ
procedure
(read-byte [in]) → (or/c byte? eof-object?)
in : input-port? = (current-input-port)
> (let ([ip (open-input-string "a")]) ; The two values in the following list should be the same. (list (read-byte ip) (char->integer #\a))) '(97 97)
> (let ([ip (open-input-string (string #\λ))]) ; This string has a two byte-encoding. (list (read-byte ip) (read-byte ip) (read-byte ip))) '(206 187 #<eof>)
procedure
(read-line [in mode]) → (or/c string? eof-object?)
in : input-port? = (current-input-port)
mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one) = 'linefeed
Characters are read from in until a line separator or an end-of-file is read. The line separator is not included in the result string (but it is removed from the port’s stream). If no characters are read before an end-of-file is encountered, eof is returned.
The mode argument determines the line separator(s). It must be one of the following symbols:
'return-linefeed breaks lines on return-linefeed combinations. If a return character is not followed by a linefeed character, it is included in the result string; similarly, a linefeed that is not preceded by a return is included in the result string.
'any breaks lines on any of a return character, linefeed character, or return-linefeed combination. If a return character is followed by a linefeed character, the two are treated as a combination.
'any-one breaks lines on either a return or linefeed character, without recognizing return-linefeed combinations.
Return and linefeed characters are detected after the conversions that are automatically performed when reading a file in text mode. For example, reading a file in text mode on Windows automatically changes return-linefeed combinations to a linefeed. Thus, when a file is opened in text mode, 'linefeed is usually the appropriate read-line mode.
> (let ([ip (open-input-string "x\ny\n")]) (read-line ip)) "x"
> (let ([ip (open-input-string "x\ny\n")]) (read-line ip 'return)) "x\ny\n"
> (let ([ip (open-input-string "x\ry\r")]) (read-line ip 'return)) "x"
> (let ([ip (open-input-string "x\r\ny\r\n")]) (read-line ip 'return-linefeed)) "x"
> (let ([ip (open-input-string "x\r\ny\nz")]) (list (read-line ip 'any) (read-line ip 'any))) '("x" "y")
> (let ([ip (open-input-string "x\r\ny\nz")]) (list (read-line ip 'any-one) (read-line ip 'any-one))) '("x" "")
procedure
(read-bytes-line [in mode]) → (or/c bytes? eof-object?)
in : input-port? = (current-input-port)
mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one) = 'linefeed
procedure
(read-string amt [in]) → (or/c string? eof-object?)
amt : exact-nonnegative-integer? in : input-port? = (current-input-port)
To read an entire port as a string, use port->string.
Returns a string containing the next amt characters from in.
If amt is 0, then the empty string is returned. Otherwise, if fewer than amt characters are available before an end-of-file is encountered, then the returned string will contain only those characters before the end-of-file; that is, the returned string’s length will be less than amt. (A temporary string of size amt is allocated while reading the input, even if the size of the result is less than amt characters.) If no characters are available before an end-of-file, then eof is returned.
If an error occurs during reading, some characters may be lost; that is, if read-string successfully reads some characters before encountering an error, the characters are dropped.
> (let ([ip (open-input-string "supercalifragilisticexpialidocious")]) (read-string 5 ip)) "super"
procedure
(read-bytes amt [in]) → (or/c bytes? eof-object?)
amt : exact-nonnegative-integer? in : input-port? = (current-input-port)
To read an entire port as bytes, use port->bytes.
> (let ([ip (open-input-bytes (bytes 6 115 101 99 114 101 116))]) (define length (read-byte ip)) (bytes->string/utf-8 (read-bytes length ip))) "secret"
procedure
(read-string! str [in start-pos end-pos])
→ (or/c exact-nonnegative-integer? eof-object?) str : (and/c string? (not/c immutable?)) in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (string-length str)
If the difference between start-pos and end-pos is 0, then 0 is returned and str is not modified. If no bytes are available before an end-of-file, then eof is returned. Otherwise, the return value is the number of characters read. If m characters are read and m<end-pos-start-pos, then str is not modified at indices start-pos+m through end-pos.
> (let ([buffer (make-string 10 #\_)] [ip (open-input-string "cketRa")]) (printf "~s\n" buffer) (read-string! buffer ip 2 6) (printf "~s\n" buffer) (read-string! buffer ip 0 2) (printf "~s\n" buffer))
"__________"
"__cket____"
"Racket____"
procedure
(read-bytes! bstr [in start-pos end-pos])
→ (or/c exact-nonnegative-integer? eof-object?) bstr : bytes? in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (bytes-length bstr)
> (let ([buffer (make-bytes 10 (char->integer #\_))] [ip (open-input-string "cketRa")]) (printf "~s\n" buffer) (read-bytes! buffer ip 2 6) (printf "~s\n" buffer) (read-bytes! buffer ip 0 2) (printf "~s\n" buffer))
#"__________"
#"__cket____"
#"Racket____"
procedure
(read-bytes-avail! bstr [in start-pos end-pos])
→ (or/c exact-nonnegative-integer? eof-object? procedure?) bstr : bytes? in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (bytes-length bstr)
When in produces a special value, as described in Custom Ports, the result is a procedure of four arguments. The four arguments correspond to the location of the special value within the port, as described in Custom Ports. If the procedure is called more than once with valid arguments, the exn:fail:contract exception is raised. If read-bytes-avail! returns a special-producing procedure, then it does not place characters in bstr. Similarly, read-bytes-avail! places only as many bytes into bstr as are available before a special value in the port’s stream.
procedure
(read-bytes-avail!* bstr [ in start-pos end-pos]) → (or/c exact-nonnegative-integer? eof-object? procedure?) bstr : bytes? in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
(read-bytes-avail!/enable-break bstr [ in start-pos end-pos]) → (or/c exact-nonnegative-integer? eof-object? procedure?) bstr : bytes? in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
(peek-string amt skip-bytes-amt [in]) → (or/c string? eof-object?)
amt : exact-nonnegative-integer? skip-bytes-amt : exact-nonnegative-integer? in : input-port? = (current-input-port)
For most kinds of ports, inspecting skip-bytes-amt bytes and amt characters requires at least skip-bytes-amt+amt bytes of memory overhead associated with the port, at least until the bytes/characters are read. No such overhead is required when peeking into a string port (see String Ports), a pipe port (see Pipes), or a custom port with a specific peek procedure (depending on how the peek procedure is implemented; see Custom Ports).
If a port produces eof mid-stream, attempts to skip beyond the eof for a peek always produce eof until the eof is read.
procedure
(peek-bytes amt skip-bytes-amt [in]) → (or/c bytes? eof-object?)
amt : exact-nonnegative-integer? skip-bytes-amt : exact-nonnegative-integer? in : input-port? = (current-input-port)
procedure
(peek-string! str skip-bytes-amt [ in start-pos end-pos]) → (or/c exact-nonnegative-integer? eof-object?) str : (and/c string? (not/c immutable?)) skip-bytes-amt : exact-nonnegative-integer? in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (string-length str)
procedure
(peek-bytes! bstr skip-bytes-amt [ in start-pos end-pos]) → (or/c exact-nonnegative-integer? eof-object?) bstr : (and/c bytes? (not/c immutable?)) skip-bytes-amt : exact-nonnegative-integer? in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
(peek-bytes-avail! bstr skip-bytes-amt [ progress in start-pos end-pos]) → (or/c exact-nonnegative-integer? eof-object? procedure?) bstr : (and/c bytes? (not/c immutable?)) skip-bytes-amt : exact-nonnegative-integer? progress : (or/c progress-evt? #f) = #f in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (bytes-length bstr)
To peek, peek-bytes-avail! blocks until finding an end-of-file, at least one byte (or special) past the skipped bytes, or until a non-#f progress becomes ready. Furthermore, if progress is ready before bytes are peeked, no bytes are peeked or skipped, and progress may cut short the skipping process if it becomes available during the peek attempt. Furthermore, progress is checked even before determining whether the port is still open.
The result of peek-bytes-avail! is 0 only
when start-pos is equal to end-pos, or
when progress becomes ready before bytes are peeked.
procedure
(peek-bytes-avail!* bstr skip-bytes-amt [ progress in start-pos end-pos]) → (or/c exact-nonnegative-integer? eof-object? procedure?) bstr : (and/c bytes? (not/c immutable?)) skip-bytes-amt : exact-nonnegative-integer? progress : (or/c progress-evt? #f) = #f in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
(peek-bytes-avail!/enable-break bstr skip-bytes-amt [ progress in start-pos end-pos]) → (or/c exact-nonnegative-integer? eof-object? procedure?) bstr : (and/c bytes? (not/c immutable?)) skip-bytes-amt : exact-nonnegative-integer? progress : (or/c progress-evt? #f) = #f in : input-port? = (current-input-port) start-pos : exact-nonnegative-integer? = 0 end-pos : exact-nonnegative-integer? = (bytes-length bstr)
procedure
(read-char-or-special [ in special-wrap source-name]) → (or/c char? eof-object? any/c) in : input-port? = (current-input-port) special-wrap : (or/c (any/c . -> . any/c) #f) = #f source-name : any/c = #f
Changed in version 6.8.0.2 of package base: Added the special-wrap and source-name arguments.
procedure
(read-byte-or-special [ in special-wrap source-name]) → (or/c byte? eof-object? any/c) in : input-port? = (current-input-port) special-wrap : (or/c (any/c . -> . any/c) #f) = #f source-name : any/c = #f
Changed in version 6.8.0.2 of package base: Added the special-wrap and source-name arguments.
procedure
(peek-char [in skip-bytes-amt]) → (or/c char? eof-object?)
in : input-port? = (current-input-port) skip-bytes-amt : exact-nonnegative-integer? = 0
procedure
(peek-byte [in skip-bytes-amt]) → (or/c byte? eof-object?)
in : input-port? = (current-input-port) skip-bytes-amt : exact-nonnegative-integer? = 0
procedure
(peek-char-or-special [ in skip-bytes-amt special-wrap source-name]) → (or/c char? eof-object? any/c) in : input-port? = (current-input-port) skip-bytes-amt : exact-nonnegative-integer? = 0 special-wrap : (or/c (any/c . -> . any/c) #f 'special) = #f source-name : any/c = #f
If special-wrap is #f, then the special value is returned (as for read-char-or-special).
If special-wrap is a procedure, then it is applied the special value to produce the result (as for read-char-or-special).
If special-wrap is 'special, then 'special is returned in place of the special value—
without calling the special-value procedure that is returned by the input-port implementation.
Changed in version 6.8.0.2 of package base: Added the special-wrap and
source-name arguments.
Changed in version 6.90.0.16: Added 'special as an option
for special-wrap.
procedure
(peek-byte-or-special [ in skip-bytes-amt progress special-wrap source-name]) → (or/c byte? eof-object? any/c) in : input-port? = (current-input-port) skip-bytes-amt : exact-nonnegative-integer? = 0 progress : (or/c progress-evt? #f) = #f special-wrap : (or/c (any/c . -> . any/c) #f 'special) = #f source-name : any/c = #f
Changed in version 6.8.0.2 of package base: Added the special-wrap and
source-name arguments.
Changed in version 6.90.0.16: Added 'special as an option
for special-wrap.
procedure
(port-progress-evt [in]) → progress-evt?
in : (and/c input-port? port-provides-progress-evts?) = (current-input-port)
procedure
(port-provides-progress-evts? in) → boolean
in : input-port?
procedure
(port-commit-peeked amt progress evt [in]) → boolean?
amt : exact-nonnegative-integer? progress : progress-evt? evt : evt? in : input-port? = (current-input-port)
The read commits only if progress does not become ready first (i.e., if no other process reads from in first), and only if evt is chosen by a sync within port-commit-peeked (in which case the event result is ignored); the evt must be either a channel-put event, channel, semaphore, semaphore-peek event, always event, or never event. Suspending the thread that calls port-commit-peeked may or may not prevent the commit from proceeding.
The result from port-commit-peeked is #t if data has been committed, and #f otherwise.
If no data has been peeked from in and progress is not ready, then exn:fail:contract exception is raised. If fewer than amt items have been peeked at the current start of in’s stream, then only the peeked items are committed as read. If in’s stream currently starts at an eof or a non-byte special value, then only the eof or special value is committed as read.
If progress is not a result of port-progress-evt applied to in, then exn:fail:contract exception is raised.
procedure
(byte-ready? [in]) → boolean?
in : input-port? = (current-input-port)
The byte-ready? and char-ready? functions are appropriate for relatively few applications, because ports are meant to support streaming data among concurrent producers and consumers; the fact that a byte or character is not ready in some instant does not necessarily mean that the producer is finished supplying data. (Also, if a port has multiple consumers, data might get consumed between the time that a given process uses byte-ready? to poll the port and the time that it reads data from the port.) Using byte-ready? makes sense if you are implementing your own scheduler or if you know that the port’s implementation and use are particularly constrained.
procedure
(char-ready? [in]) → boolean?
in : input-port? = (current-input-port)
See byte-ready? for a note on how byte-ready? and char-ready? are rarely the right choice.
procedure
(progress-evt? v) → boolean?
v : any/c (progress-evt? evt in) → boolean? evt : progress-evt? in : input-port?
With two arguments, returns #t if evt is a progress event for in, #f otherwise.