| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- :mod:`uio` -- input/output streams
- ==================================
- .. module:: uio
- :synopsis: input/output streams
- |see_cpython_module| :mod:`python: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.
|