========================== ``grail.fileutils`` module ========================== .. include:: ..\version.h .. include:: ..\Library_Reference\lib-reference.h .. contents:: Table of Contents :backlinks: top ----------- Description ----------- A collection file related general purpose routines. .. Note:: That :f:`find` is a recursive search and :f:`findindir` is a search within one directory. --------- Functions --------- :df:`chext(path, new_ext)` Takes the :a:`path` and replaces its extension with :a:`new_ext`. The :a:`new_ext` should include the dot ("."). For example, .. code-block-incl:: Python :file: ..\..\grail\test\fileutilstest.py :start: Start_ChExt_Ex :end: End_ChExt_Ex would have "c" equal to "test.doc". :df:`eq_path(a,b)` Returns :d:`True` if the path at :a:`a` is equal to the path at :a:`b`. This function is less strict than :a:`a` == :a:`b`, as it looks at each of the components, in lower-case form, and returns :d:`True` if the components match. The check is made all the way to the root of the :a:`a` and :a:`b`. :df:`find(pattern[, startdir])` [Lutz]_ Performs a recursive search for a filename pattern. Much like typing "dir *.txt" will give you a listing of all the files with the extension "txt", this function will return a listing of all the files that match the given pattern (i.e. "*.txt" or "*silly*"). Notice that this function will recursively traverse from the :a:`startdir`. predicate = lambda path: fnmatch.fnmatch(path, pattern) return filter(predicate, os.listdir(dir)) Arguments: :a:`pattern` : string Search filename pattern. :a:`startdir` : string Starting directory for the search (default = "."). Returns: A list of absolute paths that satisfy the pattern for the given starting directory and sub-directories. :df:`findindir(pattern [,dir])` Returns the files found in a directory with the given pattern. The search is non-recursive. Arguments: :a:`pattern` : string Search filename pattern. :a:`dir` : string Directory to search within (default="."). Returns: A list of strings representing files/directories that satisfy that pattern for the particular directory. Like find() all values returned are absolute paths. :df:`getdir(path)` Takes a path and returns a the directory portion. Assumes that if the path is just a filename, then the file resides in the local directory. Also, if the path is just a directory, it will return that directory back again. For example, consider we are in c:\foo\bar\ directory, then the following inputs would be, blah.dat -> c:\foo\bar c:\foo\bar -> c:\foo\bar c:\foo\bar\blah.dat -> c:\foo\bar . -> c:\foo\bar "" -> c:\foo\bar Arguments: :a:`path` : string A path (all paths will be converted to absolute paths for this function). Returns: The directory portion of the path as explained above. :df:`isreadonly(path)` Determines if a path is read only or not. Assumes that the path is actually pointing to a file (satisfying os.path.isfile()), if it is not, then behavior is undefined. This method only works on win32 machines, if you are running a non-win32 machine, this method will throw a RuntimeError. Arguments: :a:`path` : string A path that must point to a file that satisfies :f:`os.path.isfile()` [#python-lib-os-path]_. Returns: Returns :a:`0` if the file is *not* read only, returns :a:`1` if the file is read-only. :df:`makefilename(basename, extension)` Takes a :a:`basename` and an :a:`extension` and makes a file name (with the "."). Just makes the code cleaner than using [basename]+"."+[extension]. Assumes both :a:`basename` and :a:`extension` are strings. Arguments: :a:`basename` : string The file's base name. :a:`extension` : string Extension for the file. Returns: A file name of the form ".". :df:`isfileinpath (path, fln[, cwdFlg, exeFlg])` Searches supplied path for file name and returns :a:`1` if file is in the path. The search is non-recursive. Arguments: :a:`path` : string Paths delimited by os.pathsep. :a:`fln` : string File name or path used as search argument. :a:`cwdFlg` : integer :a:`1` prepends current working directory to path. :a:`0` ignores current directory.(default=1). :a:`exeFlg` : integer :a:`1` appends :a:`.exe` to the file name if it has no extension. :a:`0` does nothing.(default=0). Returns: :a:`0` - if file does not exist, :a:`1` - if file exists in path, :a:`None` - if error. :df:`notfounderrormsg([parent, fln])` Returns a formatted error message to be displayed by the calling script when file is not found in path or has no associated spawning application. Arguments: :a:`parent` : string Name of calling script. (default=" ") :a:`fln` : string File name either not in path or having no associated application. (default=" ") Returns: Formatted string: [parent].py Error: [fln] Incorrect path or path has no associated application. Please contact your System Administrator. :df:`proper_case(path)` Evaluates the :a:`path` and returns the path with the exact same case pattern as on the disk. For example, say your file, on the disk was :file:`TestFile.dat`. If you ran, .. python:: proper_case("testfile.dat") you would get back :file:`TestFile.dat`. :df:`remove_all(dirname)` Removes the directory and all its contents (include sub-directories). The :f:`os.removedirs` function from python only works if the sub-directories are empty. This function will walk through the directories recursively removing files. :df:`whereinpathisfile(path, fln[, cwdFlg])` Will find all occurrences in path that a regular file resides. Arguments: :a:`path` : string Paths of interest separated by os.pathsep :a:`fln` : string File name of interest :a:`cwdFlg` : integer If 1, prepends current directory to path prior to search. (default=1) Returns: List of strings that are the directories containing the file in the same order as path. (left to right). -------- lockfile -------- :dc:`lockfile(path[, mode, lock_type])` New in 4.60. The :c:`lockfile` class is a file-like object that builds in locking mechanics. If you use the :c:`lockfile` class to access a file on the disk, it will ensure that you can only have one reader/writer at a time. You can open the object with the same :a:`path` and :a:`mode` rules as the standard file object. All other file object methods are also available (read, write, flush, etc.). The :c:`lockfile` class allows for different types of :a:`lock_type` values. * **Exclusive** (:d:`LOCK_EX`): This means all other lock requests will *block* until the original lock is released. This means that if there is a lock on a file, an exclusive lock will not return until the lock has been released. * **Shared** (:d:`LOCK_SH`): This will allow "read" requests to the file, but not write requests. * **Non-Blocking** (:d:`LOCK_NB`): This will not block on a locked file, and will generate an :e:`fileutils.LockError` immediately. The locking mechanics only apply if you work with the :c:`lockfile` object to access the same file. If you attempt to open a locked file using the standard :c:`file` object, you will get undefined results. An example of using the lock file is as follows, .. code-block-incl:: Python :file: ..\..\grail\test\fileutilstest.py :start: Start_LockFile_Ex :end: End_LockFile_Ex the above example illustrates how you can ensure that only one file at a time locks the code. The original code was inspired by the portalocker [#portlock]_ recipe on ActiveState. -------------------------- Read Only File Like Object -------------------------- :c:`ReadOnlyFileLike(data)` This object emulates a file-like interface in a read-only mode. This is useful if you have a chunk of in memory :a:`data` that you want to keep in memory, but you want to supply a file-like interface. A good example of this is the python zipfile module, which requires a file-like interface to unpack the data. If your "zip file" is in memory, you can wrap it with the ReadOnlyFileLike and it will let you "unpack in memory". .. python:: binary_data = load_from_somewhere() filelike = fileutils.ReadOnlyFileLike(binary_data) zfile = zipfile.ZipFile(filelike, mode='r') # Do zip uncompression in the above example, the :c:`ZipFile` module will parse the :d:`filelike` object as if it where a file. This only provides "read" interfaces. If you want a "write" version, you should use the StringIO module provided by python. ----- .. [#Lutz] Lutz, Mark. *Programming Python*. 2nd Ed. 2001 (O'Reilly). .. [#python-lib-os-path] "os.path -- Common pathname manipulations." *Python Library Reference*. 21 December 2001. 12 May 2004. .. [#portlock] Jonathan Feinberg. "Recipe 65203: portalocker - Cross-platform (posix/nt) API for flock-style file locking." *ActiveState Code*. 16 May 2008. 18 Feburary 2009. '