OpenRead¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
OpenRead["file"]
opens a file for reading and returns an InputStream object; also accepts File["file"]. Returns $Failed if the file cannot be opened.
Examples (14)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic Examples (9)¶
OpenWrite truncates the file
In[1]:= str = OpenWrite["/tmp/mathilda_io_open.txt"]
Out[1]= OutputStream["/tmp/mathilda_io_open.txt", 1]
OpenAppend keeps the prior contents
In[4]:= app = OpenAppend["/tmp/mathilda_io_open.txt"]
Out[4]= OutputStream["/tmp/mathilda_io_open.txt", 2]
In[5]:= Write[app, y^2]
In[6]:= Close[app]
Out[6]= "/tmp/mathilda_io_open.txt"
In[7]:= ins = OpenRead["/tmp/mathilda_io_open.txt"]
Out[7]= InputStream["/tmp/mathilda_io_open.txt", 3]
Both lines survive the append
Applications (5)¶
Make a file
Open it for reading
First object
The current point has advanced
Implementation notes¶
Algorithm. builtin_openread calls open_common(res, output=0, append=0, "OpenRead"),
which pulls the name out of a "file" string or File["file"] (stream_filename_arg) and
calls stream_open_input. That slurps the whole file into a malloc'd buffer
(slurp_file: fopen("rb"), fseek/ftell for the size, one fread, NUL-terminate),
claims a registry slot, and records {name, buf, len, pos = 0}. The handed-back value is the
inert object InputStream["file", id] built by stream_make_object, where id is the slot's
monotonic handle. A file that cannot be opened prints OpenRead::noopen and returns $Failed.
Data structures ā the stream layer. src/io/streams.c keeps one process-global stream
registry: a dynamically grown array of Stream slots (alloc_slot doubles it; a slot with
id == 0 is free), with g_next_id a monotonic handle allocator so a reused slot never
reuses a live id. An input stream is a resident buffer plus a moving current point pos;
the integer in InputStream["file", id] indexes the registry across calls, which is how
successive Read / StreamPosition calls address the same
stream. A streams_shutdown atexit hook frees every slot's name/buf and fcloses any
open fp, so nothing leaks under valgrind.
Complexity / limits. O(file size) time and memory for the initial slurp (the entire file
is resident, so a very large file is fully loaded), then O(1) per seek. Pure ANSI C99
(fopen/fread/fseek/ftell), so no POSIX feature-test guards are needed. ATTR_PROTECTED.
Protected. Return$Failed(with anOpen*::noopendiagnostic) if the file cannot be opened.- The integer in the returned object is an internal handle into the stream registry; the object is inert and prints as itself.
- The registry is freed on
Closeor, for anything still open, at program exit (no leaks).
Attributes: Protected.
References¶
See also: OpenWrite, OpenAppend, Close
- Source:
src/io/streams.c - Specification:
docs/spec/builtins/file-io.md - Tests:
tests/test_streams.c
Notes & additional examples¶
Notes¶
OpenRead["file"] (or OpenRead[File["file"]]) opens a file for reading and
returns an InputStream["file", n] object. The whole file is slurped into a buffer
with a moving current point, so successive Read calls on the same
stream return successive objects, and StreamPosition /
SetStreamPosition query and move that point.
$Failed (with an OpenRead::noopen diagnostic) is returned when the file cannot
be opened. A named file handed directly to Read/ReadList is auto-opened, so an
explicit OpenRead is for when you want to hold the stream and advance it yourself.
Finish with Close, which returns the file name.