★ Problems with filenames
posted Fri 4 Sep 2009 by Michael Galloy under IDLWhile FILEPATH
, FILE_DIRNAME
, and FILE_BASENAME
are quite useful, the rules they follow don’t match the way I think about filenames. There are several small issues that together make them painful for me to use. In this article, I will present my problems with these routines and I’ll show the routine I use to deal with filenames.
For example, the default root directory for FILEPATH
is the IDL installation directory:
IDL> print, filepath('a.dat')
/Applications/itt/idl71/a.dat
Even if you explicitly set ROOT_DIR
to the empty string, it will still use the installation directory:
IDL> print, filepath('a.dat', root_dir='')
/Applications/itt/idl71/a.dat
To get a relative path, you need to use
IDL> print, filepath('a.dat', root='.')
./a.dat
Another issue with FILEPATH
is that the SUBDIRECTORY
keyword is ignored if TMP
is set:
IDL> print, filepath('a.dat', subdir=['b', 'c'], /tmp)
/var/folders/oi/oixrR4s-HaKpnx2R73UM+k+++TI/-Tmp-/a.dat
Since I use relative paths and temporary files a lot, these are annoying issues for me.
The routines for decomposing a filename into its constituent parts also have issues, even though they are consistent with the UNIX dirname
and basename
utilities. The UNIX utilities are written the way they are so that a filename can be decomposed by successive calls to dirname
, but I would prefer to decompose all in one step. When given a directory name to begin with, FILE_DIRNAME
fails to return the directory name provided:
IDL> print, file_dirname('a/')
.
On the other hand, FILE_BASENAME
returns a directory name (not a basename) when given a directory name:
IDL> print, file_basename('a/')
a
While this might follow the rules set forth in the documentation, this does not abide by common sense i.e for a/
, the directory name is a/
and the basename is the empty string.
The routine I have been using is MG_FILENAME
which uses the MGffFilename
class. For example, a filename can be defined as follows:
IDL> f = mg_filename('a.dat', subdir=['b', 'c'])
IDL> print, f
b/c/a.dat
Then decomposed like so:
IDL> f = mg_filename(f, basename=basename, extension=ext, $
IDL> dirname=dirname, directories=dirs)
IDL> print, f
b/c/a.dat
IDL> print, basename
a.dat
IDL> print, ext
dat
IDL> print, dirname
b/c/
IDL> print, dirs
b c
It is also more flexible with temporary files:
IDL> print, mg_filename('test.dat', subdir=['cavity'], /tmp)
/var/folders/lW/lWHkX5xME4eiMboghT4mpk+++TM/-Tmp-/cavity/test.dat
This hasn’t received a lot of use on Windows, but I use it regularly on Mac/Unix.