imcflibs.iotools

I/O related functions.

  1"""I/O related functions."""
  2
  3import glob
  4import zipfile
  5
  6import os
  7from os.path import splitext, join
  8
  9from .log import LOG as log
 10from .strtools import flatten
 11
 12
 13def filehandle(fname, mode="r"):
 14    """Make sure a variable is either a filehandle or create one from it.
 15
 16    This function takes a variable and checks whether it is already a
 17    filehandle with the desired mode or a string that can be turned into a
 18    filehandle with that mode. This can be used e.g. to make functions agnostic
 19    against being supplied a file-type parameter that was gathered via argparse
 20    (then it's already a filehandle) or as a plain string.
 21
 22    Parameters
 23    ----------
 24    fname : str or filehandle
 25    mode : str
 26        The desired mode of the filehandle (default=read).
 27
 28    Returns
 29    -------
 30    A valid (open) filehandle with the given mode. Raises an IOError
 31    otherwise.
 32
 33    Example
 34    -------
 35    >>> fname = __file__
 36    >>> type(fname)
 37    <type 'str'>
 38    >>> type(filehandle(fname))
 39    <type 'file'>
 40    >>> fh = open(__file__, 'r')
 41    >>> type(fh)
 42    <type 'file'>
 43    >>> type(filehandle(fh))
 44    <type 'file'>
 45    """
 46    log.debug(type(fname))
 47    if type(fname).__name__ == "str":
 48        try:
 49            return open(fname, mode)
 50        except IOError as err:
 51            message = "can't open '%s': %s"
 52            raise SystemExit(message % (fname, err))
 53    elif type(fname).__name__ == "file":
 54        if fname.mode != mode:
 55            message = "mode mismatch: %s != %s"
 56            raise IOError(message % (fname.mode, mode))
 57        return fname
 58    else:
 59        message = "unknown data type (expected string or filehandle): %s"
 60        raise SystemExit(message % type(fname))
 61
 62
 63def readtxt(fname, path="", flat=False):
 64    """Commodity function for reading text files plain or zipped.
 65
 66    Read a text file line by line either plainly from a directory or a .zip or
 67    .jar file. Return as a list of strings or optionally flattened into a
 68    single string.
 69
 70    BEWARE: this is NOT intended for HUGE text files as it actually reads them
 71    in and returns the content, not a handle to the reader itself!
 72
 73    Parameters
 74    ----------
 75    fname : str
 76        The name of the file to read in. Can be a full or relative path if
 77        desired. For automatic archive handling use the 'path' parameter.
 78    path : str (optional)
 79        The directory where to look for the file. If the string has the suffix
 80        '.zip' or '.jar' an archive is assumed and the corresponding mechanisms
 81        are used to read 'fname' from within this archive.
 82    flat : bool (optional)
 83        Used to request a flattened string instead of a list of strings.
 84
 85    Returns
 86    -------
 87    txt : str or list(str)
 88
 89    Example
 90    -------
 91    >>> readtxt('foo', '/tmp/archive.zip', flat=True)
 92    ... # doctest: +SKIP
 93    """
 94    zipread = None
 95    suffix = splitext(path)[1].lower()
 96    if (suffix == ".zip") or (suffix == ".jar"):
 97        # ZipFile only works as a context manager from Python 2.7 on
 98        # tag:python25
 99        zipread = zipfile.ZipFile(path, "r")
100        fin = zipread.open(fname)
101    else:
102        fin = open(join(path, fname), "r")
103    txt = fin.readlines()  # returns file as a list, one entry per line
104    if flat:
105        txt = flatten(txt)
106    fin.close()
107    if zipread is not None:
108        zipread.close()
109    return txt
def filehandle(fname, mode='r'):
14def filehandle(fname, mode="r"):
15    """Make sure a variable is either a filehandle or create one from it.
16
17    This function takes a variable and checks whether it is already a
18    filehandle with the desired mode or a string that can be turned into a
19    filehandle with that mode. This can be used e.g. to make functions agnostic
20    against being supplied a file-type parameter that was gathered via argparse
21    (then it's already a filehandle) or as a plain string.
22
23    Parameters
24    ----------
25    fname : str or filehandle
26    mode : str
27        The desired mode of the filehandle (default=read).
28
29    Returns
30    -------
31    A valid (open) filehandle with the given mode. Raises an IOError
32    otherwise.
33
34    Example
35    -------
36    >>> fname = __file__
37    >>> type(fname)
38    <type 'str'>
39    >>> type(filehandle(fname))
40    <type 'file'>
41    >>> fh = open(__file__, 'r')
42    >>> type(fh)
43    <type 'file'>
44    >>> type(filehandle(fh))
45    <type 'file'>
46    """
47    log.debug(type(fname))
48    if type(fname).__name__ == "str":
49        try:
50            return open(fname, mode)
51        except IOError as err:
52            message = "can't open '%s': %s"
53            raise SystemExit(message % (fname, err))
54    elif type(fname).__name__ == "file":
55        if fname.mode != mode:
56            message = "mode mismatch: %s != %s"
57            raise IOError(message % (fname.mode, mode))
58        return fname
59    else:
60        message = "unknown data type (expected string or filehandle): %s"
61        raise SystemExit(message % type(fname))

Make sure a variable is either a filehandle or create one from it.

This function takes a variable and checks whether it is already a filehandle with the desired mode or a string that can be turned into a filehandle with that mode. This can be used e.g. to make functions agnostic against being supplied a file-type parameter that was gathered via argparse (then it's already a filehandle) or as a plain string.

Parameters
  • fname (str or filehandle):

  • mode (str): The desired mode of the filehandle (default=read).

Returns
  • A valid (open) filehandle with the given mode. Raises an IOError
  • otherwise.
Example
>>> fname = __file__
>>> type(fname)
<type 'str'>
>>> type(filehandle(fname))
<type 'file'>
>>> fh = open(__file__, 'r')
>>> type(fh)
<type 'file'>
>>> type(filehandle(fh))
<type 'file'>
def readtxt(fname, path='', flat=False):
 64def readtxt(fname, path="", flat=False):
 65    """Commodity function for reading text files plain or zipped.
 66
 67    Read a text file line by line either plainly from a directory or a .zip or
 68    .jar file. Return as a list of strings or optionally flattened into a
 69    single string.
 70
 71    BEWARE: this is NOT intended for HUGE text files as it actually reads them
 72    in and returns the content, not a handle to the reader itself!
 73
 74    Parameters
 75    ----------
 76    fname : str
 77        The name of the file to read in. Can be a full or relative path if
 78        desired. For automatic archive handling use the 'path' parameter.
 79    path : str (optional)
 80        The directory where to look for the file. If the string has the suffix
 81        '.zip' or '.jar' an archive is assumed and the corresponding mechanisms
 82        are used to read 'fname' from within this archive.
 83    flat : bool (optional)
 84        Used to request a flattened string instead of a list of strings.
 85
 86    Returns
 87    -------
 88    txt : str or list(str)
 89
 90    Example
 91    -------
 92    >>> readtxt('foo', '/tmp/archive.zip', flat=True)
 93    ... # doctest: +SKIP
 94    """
 95    zipread = None
 96    suffix = splitext(path)[1].lower()
 97    if (suffix == ".zip") or (suffix == ".jar"):
 98        # ZipFile only works as a context manager from Python 2.7 on
 99        # tag:python25
100        zipread = zipfile.ZipFile(path, "r")
101        fin = zipread.open(fname)
102    else:
103        fin = open(join(path, fname), "r")
104    txt = fin.readlines()  # returns file as a list, one entry per line
105    if flat:
106        txt = flatten(txt)
107    fin.close()
108    if zipread is not None:
109        zipread.close()
110    return txt

Commodity function for reading text files plain or zipped.

Read a text file line by line either plainly from a directory or a .zip or .jar file. Return as a list of strings or optionally flattened into a single string.

BEWARE: this is NOT intended for HUGE text files as it actually reads them in and returns the content, not a handle to the reader itself!

Parameters
  • fname (str): The name of the file to read in. Can be a full or relative path if desired. For automatic archive handling use the 'path' parameter.
  • path (str (optional)): The directory where to look for the file. If the string has the suffix '.zip' or '.jar' an archive is assumed and the corresponding mechanisms are used to read 'fname' from within this archive.
  • flat (bool (optional)): Used to request a flattened string instead of a list of strings.
Returns
  • txt (str or list(str)):
Example
>>> readtxt('foo', '/tmp/archive.zip', flat=True)
... # doctest: +SKIP