c737cde947
Anywhere a module is mentioned, use its "non-u" name for consistency. The "import module" vs "import umodule" is something of a FAQ, and this commit intends to help clear that up. As a first approximation MicroPython is Python, and so imports should work the same as Python and use the same name, to a first approximation. The u-version of a module is a detail that can be learned later on, when the user wants to understand more and have finer control over importing. Existing Python code should just work, as much as it is possible to do that within the constraints of embedded systems, and the MicroPython documentation should match the idiomatic way to write Python code. With universal weak links for modules (via MICROPY_MODULE_WEAK_LINKS) users can consistently use "import foo" across all ports (with the exception of the minimal ports). And the ability to override/extend via "foo.py" continues to work well. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
115 lines
5.1 KiB
ReStructuredText
115 lines
5.1 KiB
ReStructuredText
:mod:`io` -- input/output streams
|
|
==================================
|
|
|
|
.. module:: io
|
|
:synopsis: input/output streams
|
|
|
|
|see_cpython_module| :mod:`cpython:io`.
|
|
|
|
This module contains additional types of ``stream`` (file-like) objects
|
|
and helper functions.
|
|
|
|
Conceptual hierarchy
|
|
--------------------
|
|
|
|
.. admonition:: Difference to CPython
|
|
:class: attention
|
|
|
|
Conceptual hierarchy of stream base classes is simplified in MicroPython,
|
|
as described in this section.
|
|
|
|
(Abstract) base stream classes, which serve as a foundation for behavior
|
|
of all the concrete classes, adhere to few dichotomies (pair-wise
|
|
classifications) in CPython. In MicroPython, they are somewhat simplified
|
|
and made implicit to achieve higher efficiencies and save resources.
|
|
|
|
An important dichotomy in CPython is unbuffered vs buffered streams. In
|
|
MicroPython, all streams are currently unbuffered. This is because all
|
|
modern OSes, and even many RTOSes and filesystem drivers already perform
|
|
buffering on their side. Adding another layer of buffering is counter-
|
|
productive (an issue known as "bufferbloat") and takes precious memory.
|
|
Note that there still cases where buffering may be useful, so we may
|
|
introduce optional buffering support at a later time.
|
|
|
|
But in CPython, another important dichotomy is tied with "bufferedness" -
|
|
it's whether a stream may incur short read/writes or not. A short read
|
|
is when a user asks e.g. 10 bytes from a stream, but gets less, similarly
|
|
for writes. In CPython, unbuffered streams are automatically short
|
|
operation susceptible, while buffered are guarantee against them. The
|
|
no short read/writes is an important trait, as it allows to develop
|
|
more concise and efficient programs - something which is highly desirable
|
|
for MicroPython. So, while MicroPython doesn't support buffered streams,
|
|
it still provides for no-short-operations streams. Whether there will
|
|
be short operations or not depends on each particular class' needs, but
|
|
developers are strongly advised to favor no-short-operations behavior
|
|
for the reasons stated above. For example, MicroPython sockets are
|
|
guaranteed to avoid short read/writes. Actually, at this time, there is
|
|
no example of a short-operations stream class in the core, and one would
|
|
be a port-specific class, where such a need is governed by hardware
|
|
peculiarities.
|
|
|
|
The no-short-operations behavior gets tricky in case of non-blocking
|
|
streams, blocking vs non-blocking behavior being another CPython dichotomy,
|
|
fully supported by MicroPython. Non-blocking streams never wait for
|
|
data either to arrive or be written - they read/write whatever possible,
|
|
or signal lack of data (or ability to write data). Clearly, this conflicts
|
|
with "no-short-operations" policy, and indeed, a case of non-blocking
|
|
buffered (and this no-short-ops) streams is convoluted in CPython - in
|
|
some places, such combination is prohibited, in some it's undefined or
|
|
just not documented, in some cases it raises verbose exceptions. The
|
|
matter is much simpler in MicroPython: non-blocking stream are important
|
|
for efficient asynchronous operations, so this property prevails on
|
|
the "no-short-ops" one. So, while blocking streams will avoid short
|
|
reads/writes whenever possible (the only case to get a short read is
|
|
if end of file is reached, or in case of error (but errors don't
|
|
return short data, but raise exceptions)), non-blocking streams may
|
|
produce short data to avoid blocking the operation.
|
|
|
|
The final dichotomy is binary vs text streams. MicroPython of course
|
|
supports these, but while in CPython text streams are inherently
|
|
buffered, they aren't in MicroPython. (Indeed, that's one of the cases
|
|
for which we may introduce buffering support.)
|
|
|
|
Note that for efficiency, MicroPython doesn't provide abstract base
|
|
classes corresponding to the hierarchy above, and it's not possible
|
|
to implement, or subclass, a stream class in pure Python.
|
|
|
|
Functions
|
|
---------
|
|
|
|
.. function:: open(name, mode='r', **kwargs)
|
|
|
|
Open a file. Builtin ``open()`` function is aliased to this function.
|
|
All ports (which provide access to file system) are required to support
|
|
``mode`` parameter, but support for other arguments vary by port.
|
|
|
|
Classes
|
|
-------
|
|
|
|
.. class:: FileIO(...)
|
|
|
|
This is type of a file open in binary mode, e.g. using ``open(name, "rb")``.
|
|
You should not instantiate this class directly.
|
|
|
|
.. class:: TextIOWrapper(...)
|
|
|
|
This is type of a file open in text mode, e.g. using ``open(name, "rt")``.
|
|
You should not instantiate this class directly.
|
|
|
|
.. class:: StringIO([string])
|
|
.. class:: BytesIO([string])
|
|
|
|
In-memory file-like objects for input/output. `StringIO` is used for
|
|
text-mode I/O (similar to a normal file opened with "t" modifier).
|
|
`BytesIO` is used for binary-mode I/O (similar to a normal file
|
|
opened with "b" modifier). Initial contents of file-like objects
|
|
can be specified with `string` parameter (should be normal string
|
|
for `StringIO` or bytes object for `BytesIO`). All the usual file
|
|
methods like ``read()``, ``write()``, ``seek()``, ``flush()``,
|
|
``close()`` are available on these objects, and additionally, a
|
|
following method:
|
|
|
|
.. method:: getvalue()
|
|
|
|
Get the current contents of the underlying buffer which holds data.
|