awips2/pythonPackages/scientific/Scientific/IO/TextFile.py
root 9f19e3f712 Initial revision of AWIPS2 11.9.0-7p5
Former-commit-id: 64fa9254b946eae7e61bbc3f513b7c3696c4f54f
2012-01-06 08:55:05 -06:00

137 lines
4.7 KiB
Python
Executable file

# Text files with automatic (un)compression and URL access.
#
# Written by: Konrad Hinsen <hinsen@cnrs-orleans.fr>
# Last revision: 2006-6-23
#
"""
Text files with line iteration and transparent compression
"""
import os, string, sys
# Use the gzip module for Python version 1.5.2 or higher
gzip = None
try:
_version = map(string.atoi,
string.split(string.split(sys.version)[0], '.'))
if _version >= [1, 5, 2]:
try:
import gzip
except ImportError:
gzip = None
except:
pass
class TextFile:
"""
Text files with line iteration and transparent compression
TextFile instances can be used like normal file objects
(i.e. by calling read(), readline(), readlines(), and write()), but
can also be used as sequences of lines in for-loops.
TextFile objects also handle compression transparently. i.e. it is
possible to read lines from a compressed text file as if it were not
compressed. Compression is deduced from the file name suffixes '.Z'
(compress/uncompress), '.gz' (gzip/gunzip), and '.bz2' (bzip2).
Finally, TextFile objects accept file names that start with '~' or
'~user' to indicate a home directory, as well as URLs (for reading only).
"""
def __init__(self, filename, mode = 'r'):
"""
@param filename: file name or URL
@type filename: C{str}
@param mode: file access mode: 'r' (read), 'w' (write), or 'a' (append)
@type mode: C{str}
"""
if string.find(filename, ':/') > 1: # URL
if mode != 'r':
raise IOError("can't write to a URL")
import urllib
self.file = urllib.urlopen(filename)
else:
filename = os.path.expanduser(filename)
if mode == 'r':
if not os.path.exists(filename):
raise IOError((2, 'No such file or directory: '
+ filename))
if filename[-2:] == '.Z':
self.file = os.popen("uncompress -c " + filename, mode)
elif filename[-3:] == '.gz':
if gzip is None:
self.file = os.popen("gunzip -c " + filename, mode)
else:
self.file = gzip.GzipFile(filename, 'rb')
elif filename[-4:] == '.bz2':
self.file = os.popen("bzip2 -dc " + filename, mode)
else:
try:
self.file = open(filename, mode)
except IOError, details:
if type(details) == type(()):
details = details + (filename,)
raise IOError(details)
elif mode == 'w':
if filename[-2:] == '.Z':
self.file = os.popen("compress > " + filename, mode)
elif filename[-3:] == '.gz':
if gzip is None:
self.file = os.popen("gzip > " + filename, mode)
else:
self.file = gzip.GzipFile(filename, 'wb')
elif filename[-4:] == '.bz2':
self.file = os.popen("bzip2 > " + filename, mode)
else:
try:
self.file = open(filename, mode)
except IOError, details:
if type(details) == type(()):
details = details + (filename,)
raise IOError(details)
elif mode == 'a':
if filename[-2:] == '.Z':
raise IOError((0, "Can't append to .Z files"))
elif filename[-3:] == '.gz':
if gzip is None:
self.file = os.popen("gzip >> " + filename, "w")
else:
self.file = gzip.GzipFile(filename, 'ab')
else:
self.file = open(filename, mode)
else:
raise IOError((0, 'Illegal mode: ' + repr(mode)))
def __del__(self):
self.close()
def __getitem__(self, item):
line = self.file.readline()
if not line:
raise IndexError
return line
def read(self, size=-1):
return self.file.read(size)
def readline(self):
return self.file.readline()
def readlines(self):
return self.file.readlines()
def write(self, data):
self.file.write(data)
def writelines(self, list):
for line in list:
self.file.write(line)
def close(self):
self.file.close()
def flush(self):
self.file.flush()