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
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'>
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