1In-Memory Files
2===============
3
4Other sections of this documentation have explained how Rasterio can access
5data stored in existing files on disk written by other programs or write files
6to be used by other GIS programs. Filenames have been the typical inputs and
7files on disk have been the typical outputs.
8
9.. code-block:: python
10
11   with rasterio.open('example.tif') as dataset:
12       data_array = dataset.read()
13
14There are different options for Python programs that have streams of bytes,
15e.g., from a network socket, as their input or output instead of filenames.
16One is the use of a temporary file on disk.
17
18.. code-block:: python
19
20    import tempfile
21
22
23    with tempfile.NamedTemporaryFile() as tmpfile:
24        tmpfile.write(data)
25        with rasterio.open(tmpfile.name) as dataset:
26            data_array = dataset.read()
27
28Another is Rasterio's ``MemoryFile``, an abstraction for objects in GDAL's
29in-memory filesystem.
30
31MemoryFile: BytesIO meets NamedTemporaryFile
32--------------------------------------------
33
34The ``MemoryFile`` class behaves a bit like ``BytesIO`` and
35``NamedTemporaryFile``.  A GeoTIFF file in a sequence of ``data`` bytes can be
36opened in memory as shown below.
37
38.. code-block:: python
39
40   from rasterio.io import MemoryFile
41
42
43    with MemoryFile(data) as memfile:
44        with memfile.open() as dataset:
45            data_array = dataset.read()
46
47This code can be several times faster than the code using
48``NamedTemporaryFile`` at roughly double the price in memory.
49
50Writing MemoryFiles
51-------------------
52
53Incremental writes to an empty ``MemoryFile`` are also possible.
54
55.. code-block:: python
56
57    with MemoryFile() as memfile:
58        while True:
59            data = f.read(8192)  # ``f`` is an input stream.
60            if not data:
61                break
62            memfile.write(data)
63        with memfile.open() as dataset:
64            data_array = dataset.read()
65
66These two modes are incompatible: a ``MemoryFile`` initialized with a sequence
67of bytes cannot be extended.
68
69An empty ``MemoryFile`` can also be written to using dataset API methods.
70
71.. code-block:: python
72
73   with MemoryFile() as memfile:
74       with memfile.open(driver='GTiff', count=3, ...) as dataset:
75           dataset.write(data_array)
76
77Reading MemoryFiles
78-------------------
79
80Like ``BytesIO``, ``MemoryFile`` implements the Python file protocol and
81provides ``read()``, ``seek()``, and ``tell()`` methods. Instances are thus suitable
82as arguments for methods like `requests.post() <https://requests.readthedocs.io/en/latest/api/#requests.post>`__.
83
84.. code-block:: python
85
86   with MemoryFile() as memfile:
87       with memfile.open(driver='GTiff', count=3, ...) as dataset:
88           dataset.write(data_array)
89
90        requests.post('https://example.com/upload', data=memfile)
91