The ``File`` object
===================

The :mod:`django.core.files` module and its submodules contain built-in classes
for basic file handling in Django.

.. currentmodule:: django.core.files

The ``File`` Class
------------------

.. class:: File(file_object)

    The :class:`File` is a thin wrapper around Python's built-in file object
    with some Django-specific additions. Internally, Django uses this class
    any time it needs to represent a file.
    
    :class:`File` objects have the following attributes and methods:

    .. attribute:: name

        The name of file including the relative path from
        :setting:`MEDIA_ROOT`.

    .. attribute:: size

        The size of the file in bytes.

    .. attribute:: file

        The underlying Python ``file`` object passed to
        :class:`~django.core.files.File`.

    .. attribute:: mode

        The read/write mode for the file.

    .. method:: open([mode=None])

        Open or reopen the file (which by definition also does
        ``File.seek(0)``). The ``mode`` argument allows the same values
        as Python's standard ``open()``.

        When reopening a file, ``mode`` will override whatever mode the file
        was originally opened with; ``None`` means to reopen with the original
        mode.

    .. method:: read([num_bytes=None])

        Read content from the file. The optional ``size`` is the number of
        bytes to read; if not specified, the file will be read to the end.

    .. method:: __iter__()

        Iterate over the file yielding one line at a time.

    .. method:: chunks([chunk_size=None])

        Iterate over the file yielding "chunks" of a given size. ``chunk_size``
        defaults to 64 KB.

        This is especially useful with very large files since it allows them to
        be streamed off disk and avoids storing the whole file in memory.

    .. method:: multiple_chunks([chunk_size=None])

        Returns ``True`` if the file is large enough to require multiple chunks
        to access all of its content give some ``chunk_size``.

    .. method:: write([content])

        Writes the specified content string to the file. Depending on the
        storage system behind the scenes, this content might not be fully
        committed until ``close()`` is called on the file.

    .. method:: close()

        Close the file.

    In addition to the listed methods, :class:`~django.core.files.File` exposes
    the following attributes and methods of the underlying ``file`` object:
    ``encoding``, ``fileno``, ``flush``, ``isatty``, ``newlines``,
    ``read``, ``readinto``, ``readlines``, ``seek``, ``softspace``, ``tell``,
    ``truncate``, ``writelines``, ``xreadlines``.

.. currentmodule:: django.core.files.base

The ``ContentFile`` Class
-------------------------

.. class:: ContentFile(File)

    The ``ContentFile`` class inherits from :class:`~django.core.files.File`,
    but unlike :class:`~django.core.files.File` it operates on string content,
    rather than an actual file. For example::

        from django.core.files.base import ContentFile

        f1 = ContentFile("my string content")
        f2 = ContentFile(u"my unicode content encoded as UTF-8".encode('UTF-8'))

.. currentmodule:: django.core.files.images

The ``ImageFile`` Class
-----------------------

.. class:: ImageFile(file_object)

    Django provides a built-in class specifically for images.
    :class:`django.core.files.images.ImageFile` inherits all the attributes
    and methods of :class:`~django.core.files.File`, and additionally
    provides the following:

    .. attribute:: width

        Width of the image in pixels.

    .. attribute:: height

        Height of the image in pixels.

.. currentmodule:: django.core.files

Additional methods on files attached to objects
-----------------------------------------------

Any :class:`File` that's associated with an object (as with ``Car.photo``,
below) will also have a couple of extra methods:

.. method:: File.save(name, content, [save=True])

    Saves a new file with the file name and contents provided. This will not
    replace the existing file, but will create a new file and update the object
    to point to it. If ``save`` is ``True``, the model's ``save()`` method will
    be called once the file is saved. That is, these two lines::

        >>> car.photo.save('myphoto.jpg', contents, save=False)
        >>> car.save()

    are the same as this one line::

        >>> car.photo.save('myphoto.jpg', contents, save=True)

    Note that the ``content`` argument must be an instance of either
    :class:`File` or of a subclass of :class:`File`, such as
    :class:`ContentFile`.

.. method:: File.delete([save=True])

    Removes the file from the model instance and deletes the underlying file.
    If ``save`` is ``True``, the model's ``save()`` method will be called once
    the file is deleted.
