JMRI Code: Portable File Access
JMRI uses files for icons, images, panel files, scripts, and lots of other things.
References to those are routinely used by various code, and stored in XML files. Some of the
files are distributed with JMRI, and some are created outside the JMRI distribution directory
by the local user.
In addition, JMRI is a cross-platform application, and we want to be able to move JMRI XML
files from one computer to another, even of a different type, and have them still work.
To do this, we've created a system of pseudo-URLs for accessing file locations. Filenames
are used internally and stored in XML files with prefixes that identify where the file is to
be found in a system independent manner.
- program:
- Treats the path as a relative path below the JMRI installation directory. In JMRI
2.13.1 and earlier, this was the
resources:
prefix.
- preference:
- Treats the path as a relative path below the user files (or preferences) directory. In
JMRI 2.13.1 and earlier, thie was the
file:
prefix.
- profile:
- Treats the path as a relative path below the configuration profile directory.
- settings:
- Treats the path as a relative path below the settings directory (the directory where
per-computer preferences are stored).
- home:
- Treats the path as a relative path below the user's home directory.
Otherwise, treat the name as a relative path below the program directory to provide backward
compatibility. In any case, absolute pathnames will work, but won't be cross-platform
compatible.
Implementation
The
jmri.util.FileUtil
class provides translation routines to make this automatic:
- static public String getExternalFilename(String pName)
- Convert an internal name (with prefixes as above) into an absolute pathname for use on
the local computer. There's no guarantee that the file or any enclosing directory is
actually present, but the pathname will be syntactically valid on the present
computer.
- static public String getPortableFilename(File file)
- static public String getPortableFilename(String filename)
- Convert a File or filename string into a string name with the appropriate prefix.
You should call getExternalFilename() before passing the filename to any Java common, and
getPortableFilename() whenever you get a file or filename from a Java class. It's OK to call
either one multiple times, as they'll just pass through in that case. In particular, call
getPortableFilename() before storing to an XML file.