It requires a relatively small number of methods to implement a working FS object.
It requires a relatively small number of methods to implement a working FS object.
If you are looking to implement a working FS object, derive a class from fs.base.FS and implement the essential methods (below). Be sure to convert all exceptions to instances of :class:`fs.errors.FSError`.
If you are looking to implement a working FS object, derive a class from :py:class:`fs.base.FS` and implement the essential methods (below). Be sure to convert all exceptions to instances of :class:`fs.errors.FSError`.
It may also be worthwhile implementing some of the non-essential methods, as the default implementations may not be optimal. For example, the method :meth:`fs.base.FS.move` is implemeneted as a file copy followed by a delete, but many filesystems can move a file without copying data.
It may also be worthwhile implementing some of the non-essential methods, as the default implementations may not be optimal. For example, the method :meth:`fs.base.FS.move` is implemented as a file copy followed by a delete, but many filesystems can move a file without copying data.
If the filesystem you are implementing maps paths to the native filesystem, be sure to implement `getsyspath`. Doing so will improve performance, especialy when copying / moving files between FS objects.
If the filesystem you are implementing maps paths to the native filesystem, be sure to implement :py:meth:`~fs.base.FS.getsyspath`. Doing so will improve performance, especially when copying / moving files between FS objects.
Essential Methods
Essential Methods
-----------------
-----------------
...
@@ -28,7 +28,7 @@ The following methods are required for a minimal Filesystem interface:
...
@@ -28,7 +28,7 @@ The following methods are required for a minimal Filesystem interface:
Non - Essential Methods
Non - Essential Methods
-----------------------
-----------------------
The following methods have default implementations in fs.base.FS and aren't required for a functional FS interface. They may be overriden if an alternative implementation can be supplied:
The following methods have default implementations in :py:class:`fs.base.FS` and aren't required for a functional FS interface. They may be overriden if an alternative implementation can be supplied:
* :meth:`~fs.base.FS.copy` Copy a file to a new location
* :meth:`~fs.base.FS.copy` Copy a file to a new location
* :meth:`~fs.base.FS.copydir` Recursively copy a directory to a new location
* :meth:`~fs.base.FS.copydir` Recursively copy a directory to a new location
...
@@ -53,7 +53,7 @@ The following methods have default implementations in fs.base.FS and aren't requ
...
@@ -53,7 +53,7 @@ The following methods have default implementations in fs.base.FS and aren't requ
Utility Methods
Utility Methods
---------------
---------------
The following members have implementations in fs.base.FS and will probably never require a non-default implementation, although there is nothing to prevent a derived class from implementing these:
The following members have implementations in :py:class:`fs.base.FS` and will probably never require a non-default implementation, although there is nothing to prevent a derived class from implementing these:
* :meth:`~fs.base.FS.createfile` Create a file with data
* :meth:`~fs.base.FS.createfile` Create a file with data
* :meth:`~fs.base.FS.getcontents` Returns the contents of a file as a string
* :meth:`~fs.base.FS.getcontents` Returns the contents of a file as a string
Generally, when you want to work with the files and directories of any of the supported filesytems,
you create an instance of the appropriate class. For example, the following opens the directory /foo/bar::
from fs.osfs import OSFS
my_fs = OSFS('/foo/bar')
This is fine if you know beforehand where the directory you want to work with is located, and on what medium.
However, there are occasions where the location of the files may change at runtime or should be specified in a config file or from the command line.
In these situations you can use an _opener_ which is a generic way of specifying a filesystem. For example, the following is equivalent to the code above::
from fs.opener import fsopen
my_fs = fsopen('/foo/bar')
The `fsopen` method takes a string that identifies the filesystem, but if called with a regular path, it will return an OSFS instance.
To open a different kind of filesystem, you specify it with a URI like syntax. The following code opens an ftp filesystem rather than a directory on your harddrive::
from fs.opener import fsopen
my_fs = fsopen('ftp://example.org/foo/bar')
For further information regarding filesystem openers see :doc:`opener`.
There are occasions when you want to specify a filesytem from the command line or in a config file.
There are occasions when you want to specify a filesytem from the command line or in a config file.
This module enables that functionality, and can return a FS object given a URI like syntax (http://commons.apache.org/vfs/filesystems.html).
This module enables that functionality, and can return an FS object given a URI like syntax (http://commons.apache.org/vfs/filesystems.html).
The `OpenerRegistry` class maps the protocol (file, ftp etc.) on to an Opener object, which returns an appropriate filesystem object and path.
The `OpenerRegistry` class maps the protocol (file, ftp etc.) on to an Opener object, which returns an appropriate filesystem object and path.
You can create a custom opener registry that opens just the filesystems you require, or use the opener registry defined here (also called `opener`) that can open any supported filesystem.
You can create a custom opener registry that opens just the filesystems you require, or use the opener registry defined here (also called `opener`) that can open any supported filesystem.
The `parse` method of an `OpenerRegsitry` object returns a tuple of an FS object a path. Here's an example of how to use the default opener registry::
The `parse` method of an `OpenerRegsitry` object returns a tuple of an FS object a path. Here's an example of how to use the default opener registry::
>>> from fs.opener import opener
>>> from fs.opener import opener
>>> opener.parse('ftp://ftp.mozilla.org')
>>> opener.parse('ftp://ftp.mozilla.org/pub')
(<fs.ftpfs.FTPFS object at 0x96e66ec>, u'pub')
(<fs.ftpfs.FTPFS object at 0x96e66ec>, u'pub')
You can use use the `opendir` method, which just returns an FS object. In the example above, `opendir` will return a FS object for the directory `pub`::
You can use use the `opendir` method, which just returns an FS object. In the example above, `opendir` will return a FS object for the directory `pub`::
...
@@ -26,12 +26,11 @@ If you are just interested in a single file, use the `open` method of a registry
...
@@ -26,12 +26,11 @@ If you are just interested in a single file, use the `open` method of a registry
<fs.ftpfs._FTPFile object at 0x973764c>
<fs.ftpfs._FTPFile object at 0x973764c>
The `opendir` and `open` methods can also be imported from the top-level of this module for sake of convenience.
The `opendir` and `open` methods can also be imported from the top-level of this module for sake of convenience.
To avoid shadowing the builtin `open` methd, they are named `fsopendir` and `fsopen`. Here's how you might import them::
To avoid shadowing the builtin `open` method, they are named `fsopendir` and `fsopen`. Here's how you might import them::