Recently I ported Exaile’s Files panel to use GIO instead of Python’s
os module. The reason is simple: remote browsing.
Yes, you can now browse an SMB share or an SFTP server through the Files panel. Just mount the remote filesystem with
gvfs-mount and enter the URL into the location bar. Previously Aren ported Exaile’s core to GIO as well, so remote files can be played just fine.
This is the kind of convenience you get out of using GIO/GVFS. In this article I’ll briefly explain what GIO is and how to do some basic file operations—similar to what the Files panel does—using GIO.
What is GIO? GVFS? GnomeVFS?
GIO is an input/output framework. It provides a bunch of functionalities related to files, directories, removable media, networks, and other stuff that fall under the IO category. This article’s focus—file operations—is just one of its features.
GVFS complements GIO by letting it access remote/virtual filesystems (the VFS part of the name).
GnomeVFS is an older technology that GIO and GVFS together replace.
GIO is distributed as part of GLib, while GVFS sits in a separate package. GnomeVFS was part of GNOME and is being phased out.
GFile, the bread and butter of file operations
This is the file class in GIO. By itself GFile represents nothing more than a URI, but it lets you do all sorts of operations on a file or directory. Here’s a simple example:
>>> import gio >>> f = gio.File('.') >>> f.get_uri() file:///home/user >>> f.get_path() /home/user >>> f.delete() Traceback (most recent call last): ... gio.Error: Error removing file: Directory not empty
GFileInfo represents various properties of a file or stream, such as size, permissions, etc. To obtain the GFileInfo of a file, call GFile’s
>>> f = gio.File('.') >>> info = f.query_info('standard::type,standard::size') >>> info.get_file_type() <enum G_FILE_TYPE_DIRECTORY of type GFileType> >>> info.get_size() 0L
query_info requires a list of attributes that you want to retrieve. Only the specified attributes are then populated into the GFileInfo. Multiple attributes can be queried by separating them with commas. Wildcards in the form of
namespace::* are also accepted.
In this example, we query the file type and size (by the way, the size is always 0 for directories). The results are stored in the returned GFileInfo.
To retrieve a value from GFileInfo, call its
get_attribute_* methods (e.g.
get_attribute_uint32("standard::type")). Some attributes have special getters (e.g.
Example: getting parent directory
This is just a very simple example showing how to get the parent of a directory.
import gio current = gio.File('.') parent = current.get_parent()
Example: getting contents of a directory
This example shows the meat of the Files panel: displaying the subdirectories and files inside a directory. For each file, we also obtain its size.
import gio current = gio.File('.') subdirs =  files =  infos = current.enumerate_children( 'standard::name,standard::type,standard::size') for info in infos: child = current.get_child(info.get_name()) if info.get_file_type() == gio.FILE_TYPE_DIRECTORY: subdirs.append(child) else: files.append((child, info.get_size()))
enumerate_children works similarly to
query_info, but it retrieves the properties of all the children of a directory.
That’s it, we’ve covered everything essential for a file browser. The Files panel just builds a GUI and a history feature on top.
I’ve written a small demonstration of a working GIO file browser; try giving it a remote location to browse (don’t forget to
gvfs-mount the filesystem first).