Jump to: navigation, search

EFS for Platform Committers

This page contains information about the Eclipse File System API (EFS) for developers working on code in the Eclipse platform. While some of this information may be useful to others, it focuses on platform usage of EFS and may discuss internal platform details that are not applicable outside the platform.

Path versus Location

There is an important difference in platform terminology between an IResource's path and location. The workspace itself can be viewed as a simple tree, with IWorkspaceRoot at the root, IProject at the first level, and IFolder/IFile nested to any depth within each project. Resources also exist in some file system, and each file system can be represented as a tree. However, the workspace tree and the file system tree are not necessarily the same. For example, each IProject can be associated with a different file system, and each linked resource can be connected to a different file system. So, we need a way of finding resources within the workspace tree, and also a way to find resources in the file system.

The path of a resource is the position of the resource in the workspace tree. A resource's path is obtained by calling IResource.getFullPath(). A resource path is always represented by an IPath object.

The location of a resource is the position of the resource in the file system. A resource's location is obtained by calling IResource.getLocationURI(). Before the introduction of EFS, the resource location was also represented using IPath (IResource.getLocation()). However, using IPath to represent a resource's location in the file system is obsolete since Eclipse 3.2. The file system location of a resource must always be represented as a URI. This is because IPath doesn't have powerful enough syntax to represent different kinds of file systems - it is purely for the local file system.

If you see code that uses IPath when dealing with a resource location on disk, it is wrong, and must be migrated to use URI. The same is true for all "location" methods that use IPath, such as IResource.getLocation(), IProjectDescription.getLocation(), etc. These methods exist only for backwards compatibility.

Converting from path to location

Given a workspace path, it is fairly straightforward to obtain a location:

IPath somePath = ...;//the path you want to find the location for
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IResource resource = root.findMember(someLocation);
if (resource != null) {
    URI location = resource.getLocationURI();
}

Converting from a location to a path

Finding a resource path corresponding to a given location is a bit more expensive. Also, because of linked resources, you can have an arbitrary number of resources associated with a given location. If you don't know whether the location corresponds to a file or directory, you will need to find that out first.

URI someLocation = ...;//the location you want to find the resource path for
boolean isDir = EFS.getStore(someLocation).fetchInfo().isDirectory();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
if (isDir) {
    IFolder[] folders = root.findContainersForLocationURI(someLocation);
} else {
    IFile[] files = root.findFilesForLocationURI(someLocation);
}

Note that these "find*" methods are not fast because they have to search through the workspace to find matching resources. Use with caution. If you find yourself doing this in a loop, consider if there are other approaches to your problem.


Converting between IPath locations and URI locations

When working with backward compatibility code, you may need to deal with locations represented by IPath. The best approach is to rewrite as much as possible to use URI, and then convert from IPath to URI whenever necessary. The org.eclipse.core.filesystem.URIUtil class has a convenience method for doing this:

IPath locationAsPath = ...;//some location in IPath form
URI locationAsURI = URIUtil.toURI(locationAsPath);

Similarly, you can convert from URI to IPath, but only if you know for sure that the URI is in the local file system.

URI locationAsURI = ...;//some location in URI form
if (EFS.SCHEME_FILE.equals(locationAsURI.getScheme())) {
    IPath locationAsPath = URIUtil.toPath(locationAsURI);
}

URI versus IFileStore

The first thing you will notice about URI is that it's not a very useful class. It has very few convenience methods, and it has no methods at all that allow you to interact with the file system - read an input stream, create, delete, etc. URI is purely an abstraction - it is just the unique name of some object, but defines no methods for interacting with that object. This is where IFileStore comes in. IFileStore has all the methods you would expect for dealing with files: copy, move, delete, mkdir, open input stream, open output stream, etc. Here are some useful documents to learn about using IFileStore:

Unittests

EFS Unittests are in

Repository :pserver:anonymous@dev.eclipse.org:/cvsroot/eclipse
Module org.eclipse.core.tests.resources
Requires also: org.eclipse.core.tests.harness, org.eclipse.test.performance
Packages org.eclipse.core.tests.filesystem
org.eclipse.core.tests.internal.filesystem.*



Back to Eclipse File System API home