org.openide.filesystems.doc-files.api.html Maven / Gradle / Ivy
Filesystems API
Javadoc
Take a look at the
Javadoc,
especially for
FileObject
.
Contents
Filesystems API
The Filesystems API permits module authors to access files in a uniform manner:
e.g. you may be unaware of whether a "file object" you are using is a plain disk file, or a JAR entry.
A FileSystem is a namespace for FileObjects - a FileSystem
has a root folder, which is a FileObject, which may have child files and folders -
just like a file system on disk. A FileSystem may or may not represent
actual files on disk; this API can be used to represent any hierarchical
storage of file-like data.
What This API is Not For
This API pertains only to manipulating files on disk (or whatever
storage mechanism a filesystem may use), and makes no reference to
their contents nor to how they are being used elsewhere in NetBeans
(beyond whether or not they are locked). If you are looking for
information on how to create custom content types, use the editor,
create Explorer nodes corresponding to files, etc., this API is not
the primary document you should be reading.
From the perspective of the Filesystems API, all files consist of
byte streams (albeit with MIME types). Usually, the functionality of
this API will actually be used indirectly, via the
Loaders API,
which abstracts away most of the details of files and presents data in
terms of DataObjects,
which typically represent the parsed content of a file and provide
objects to programmatically access that content via
DataObject.getCookie().
Common Tasks
Basic operations using the Filesystems API should be familiar,
as they are similar to any file-access system. FileObjects
for a user's data on disk are typically a thin wrapper around
java.io.File
; elements of NetBeans' internal configuration
are also FileObjects
, these typically representing data
actually stored in an XML file inside a module's jar.
There are a few differences from traditional file-access APIs, such as
monitoring files/folders for changes. This
section gives examples of the more common tasks associated with using
filesystems.
Finding files and folders
Normally, you will be looking for a file or folder by name, and will want to get the
FileObject
which represents it.
If you need to get a file object corresponding to a file on disk, use:
fileObject = FileUtil.toFileObject(new File("/some/path/to/file.txt"));
FileUtil
also has methods for working with archive (ZIP/JAR) entries. File objects corresponding
to archive entries are read-only but otherwise behave much like disk files.
To find all the folders and files directly contained in this
folder, you may use:
FileObject children[]=folder.getChildren();
Occasionally you may need to present a given file object as a URL; for example, to display it in
a web browser. This is straightforward:
URL url = file.getURL();
HtmlBrowser.URLDisplayer.getDefault().showURL(url);
Creating, deleting, and renaming files and folders
This example creates a subfolder and then a new file within that
subfolder:
FileObject subfolder=folder.createFolder("sub");
FileObject newfile=subfolder.createData("NewSource", "java");
You can delete a file easily:
newfile.delete();
If you want to rename a file, you must first take out a
lock
on the file, to make sure that no one else is actively using the file
at the same time. Then you may rename it:
FileLock lock = null;
try {
lock=newfile.lock();
} catch (FileAlreadyLockedException e) {
// Try again later; perhaps display a warning dialog.
return;
}
try {
newfile.rename(lock, "NewSrc", "java");
} finally {
// Always put this in a finally block!
lock.releaseLock();
}
If you want to move a file into a different directory (or even file
system), you cannot use rename(...)
; the easiest way is
to use a NetBeans helper method:
FileObject someFile;
FileObject whereTo;
FileUtil.moveFile(someFile, whereTo, "YourSource");
Note that in the current API set, it is neither possible nor
necessary to lock folders (e.g. when creating new children), as
normally locks are used to protect data files from conflicts between
the Editor, the Explorer, and so on. If in the future there are
thread-related problems associated with improper simultaneous access
to the same folder, support for folder
locking could be added to the Filesystems API.
Similarly, there is no support currently for nonexclusive read
locks - if you require exclusion of writers during a read, you must
take out a regular write lock for the duration of the read. This is
not normally necessary, since typically only the Editor will be
reading and writing the contents of the file, and other file
operations do not involve information which could be partially
corrupted between threads. If necessary, the API includes
facilities for
read-many/write-one locks.
Reading and writing files
Reading and writing the contents of a data file is straightforward:
BufferedReader from=new BufferedReader(new InputStreamReader(someFile.getInputStream()));
try {
String line;
while ((line=from.readLine()) != null) {
// do something with line
} finally {
from.close();
}
FileLock lock;
try {
lock=someFile.lock();
} catch (FileAlreadyLockedException e) {
return;
}
try {
PrintWriter to=new PrintWriter(someFile.getOutputStream(lock));
try {
to.println("testing...");
to.println("1..2..3..");
} finally {
to.close();
}
} finally {
lock.releaseLock();
}
Listening on file events
If you need to keep track of what is being done to a file by other
components, you can monitor it using normal Java events:
someFile.addFileChangeListener(new FileChangeAdapter() {
public void fileChanged(FileEvent ev) {
System.out.println("Contents changed.");
}
public void fileAttributeChanged(FileAttributeEvent ev) {
System.out.println(ev.getName() + ": " + ev.getOldValue() + " -> " + ev.getNewValue());
}
});
All events affecting existing files are actually fired twice, once
from the file itself and once from its containing folder, so you may
just want to listen on the parent folder. Also, file creation events
are fired on the folder only, of course:
FileObject someFolder=someFile.getParent();
someFolder.addFileChangeListener(new FileChangeAdapter() {
public void fileChanged(FileEvent ev) {
System.out.println("Contents of " + ev.getFile() + " changed.");
}
public void fileDataCreated(FileEvent ev) {
System.out.println("File " + ev.getFile() + " created.");
}
});
Determining MIME Content Type
FileObject.getMIMEType()
reports a basic MIME type for a file, which can used to classify it for
editing and other purposes.
If you need to influence the MIME type resolution process, you can register a MIMEResolver
.
To simplify this process you can register a MIMEResolver
declaratively.
It is not only easier (no coding needed) but can be more efficient by
sharing results among multiple declared resolvers.
See the declarative MIME resolvers how-to for more information about this.
Special Filesystems
Each file object resides on a FileSystem
which handles a large tree of files. Normally you need
not be aware of this, since the "Master Filesystem" module automatically handles creation of whatever
FileSystem
s are needed to represent any files on disk, as well as any ZIP/JAR entries for archives
on disk (using JarFileSystem
). It is possible to implement your own filesystem for specialized
purposes (normally by subclassing AbstractFileSystem
and perhaps registering a corresponding
URLMapper
).
The Filesystems API also includes a couple of special implementations which are used by the NetBeans core
to assemble the system filesystem used for application configuration, and could also be used by module writers
in some circumstances: MultiFileSystem
and XMLFileSystem
. See their Javadoc for more
information.
@FOOTER@