Ejemplo n.º 1
0
    def _open_filename(self, filename, mode):
        """Open a FITS file from a filename string."""

        if os.path.exists(self.name):
            with fileobj_open(self.name, 'rb') as f:
                magic = f.read(4)
        else:
            magic = ''.encode('raw-unicode-escape')
        ext = os.path.splitext(self.name)[1]
        if ext == '.gz' or magic.startswith(GZIP_MAGIC):
            # Handle gzip files
            self.__file = gzip.open(self.name, PYTHON_MODES[mode])
            self.compression = 'gzip'
        elif ext == '.zip' or magic.startswith(PKZIP_MAGIC):
            # Handle zip files
            if mode in ['update', 'append']:
                raise IOError(
                      "Writing to zipped fits files is not currently "
                      "supported")
            zfile = zipfile.ZipFile(self.name)
            namelist = zfile.namelist()
            if len(namelist) != 1:
                raise IOError(
                  "Zip files with multiple members are not supported.")
            self.__file = tempfile.NamedTemporaryFile(suffix='.fits')
            self.__file.write(zfile.read(namelist[0]))
            zfile.close()
            self.compression = 'zip'
        else:
            self.__file = fileobj_open(self.name, PYTHON_MODES[mode])
            # Make certain we're back at the beginning of the file
        self.__file.seek(0)
Ejemplo n.º 2
0
    def _open_fileobj(self, fileobj, mode):
        """Open a FITS file from a file object or a GzipFile object."""

        closed = fileobj_closed(fileobj)
        fmode = fileobj_mode(fileobj) or PYTHON_MODES[mode]

        if not closed:
            # In some cases (like on Python 3) a file opened for appending
            # still shows a mode of 'r+', hence the extra check for the append
            # case
            if ((mode == 'append' and fmode not in ('ab+', 'rb+')) or
                (mode != 'append' and PYTHON_MODES[mode] != fmode)):
                raise ValueError(
                    "Input mode '%s' (%s) does not match mode of the "
                    "input file (%s)." % (mode, PYTHON_MODES[mode], fmode))
            self.__file = fileobj
        elif isfile(fileobj):
            self.__file = fileobj_open(self.name, PYTHON_MODES[mode])
            # Return to the beginning of the file--in Python 3 when opening in
            # append mode the file pointer is at the end of the file
            self.__file.seek(0)
        else:
            self.__file = gzip.open(self.name, PYTHON_MODES[mode])
Ejemplo n.º 3
0
    def __init__(self, fileobj=None, mode='readonly', memmap=False):
        if fileobj is None:
            self.__file = None
            self.closed = False
            self.mode = mode
            self.memmap = memmap
            self.compression = None
            self.readonly = False
            self.writeonly = False
            self.simulateonly = True
            return
        else:
            self.simulateonly = False

        if mode not in PYTHON_MODES:
            raise ValueError("Mode '%s' not recognized" % mode)

        if (isinstance(fileobj, basestring) and mode != 'append' and
            not os.path.exists(fileobj) and
            not os.path.splitdrive(fileobj)[0]):
                #
                # Not writing file and file does not exist on local machine and
                # name does not begin with a drive letter (Windows), try to
                # get it over the web.
                #
            self.name, _ = urllib.urlretrieve(fileobj)
        else:
            self.name = fileobj_name(fileobj)

        self.closed = False
        self.mode = mode
        self.memmap = memmap

        # Underlying fileobj is a file-like object, but an actual file object
        self.file_like = False

        # More defaults to be adjusted below as necessary
        self.compression = None
        self.readonly = False
        self.writeonly = False

        # Initialize the internal self.__file object
        if isfile(fileobj) or isinstance(fileobj, gzip.GzipFile):
            closed = fileobj_closed(fileobj)
            fmode = fileobj_mode(fileobj) or PYTHON_MODES[mode]

            if not closed:
                # In some cases (like on Python 3) a file opened for
                # appending still shows a mode of 'r+', hence the extra
                # check for the append case
                if ((mode == 'append' and fmode not in ('ab+', 'rb+')) or
                    (mode != 'append' and PYTHON_MODES[mode] != fmode)):
                    raise ValueError(
                        "Input mode '%s' (%s) does not match mode of the "
                        "input file (%s)." % (mode, PYTHON_MODES[mode], fmode))
                self.__file = fileobj
            elif isfile(fileobj):
                self.__file = fileobj_open(self.name, PYTHON_MODES[mode])
                # Return to the beginning of the file--in Python 3 when
                # opening in append mode the file pointer is at the end of
                # the file
                self.__file.seek(0)
            else:
                self.__file = gzip.open(self.name, PYTHON_MODES[mode])
        elif isinstance(fileobj, basestring):
            if os.path.exists(self.name):
                with fileobj_open(self.name, 'rb') as f:
                    magic = f.read(4)
            else:
                magic = ''.encode('raw-unicode-escape')
            ext = os.path.splitext(self.name)[1]
            if ext == '.gz' or magic.startswith(GZIP_MAGIC):
                # Handle gzip files
                if mode in ['update', 'append']:
                    raise IOError(
                          "Writing to gzipped fits files is not currently "
                          "supported")
                self.__file = gzip.open(self.name)
                self.compression = 'gzip'
            elif ext == '.zip' or magic.startswith(PKZIP_MAGIC):
                # Handle zip files
                if mode in ['update', 'append']:
                    raise IOError(
                          "Writing to zipped fits files is not currently "
                          "supported")
                zfile = zipfile.ZipFile(self.name)
                namelist = zfile.namelist()
                if len(namelist) != 1:
                    raise IOError(
                      "Zip files with multiple members are not supported.")
                self.__file = tempfile.NamedTemporaryFile(suffix='.fits')
                self.__file.write(zfile.read(namelist[0]))
                zfile.close()
                self.compression = 'zip'
            else:
                self.__file = fileobj_open(self.name, PYTHON_MODES[mode])
                # Make certain we're back at the beginning of the file
            self.__file.seek(0)
        else:
            # We are dealing with a file like object.
            # Assume it is open.
            self.file_like = True
            self.__file = fileobj

            # If there is not seek or tell methods then set the mode to
            # output streaming.
            if (not hasattr(self.__file, 'seek') or
                not hasattr(self.__file, 'tell')):
                self.mode = mode = 'ostream'

            if (self.mode in ('copyonwrite', 'update', 'append') and
                not hasattr(self.__file, 'write')):
                raise IOError("File-like object does not have a 'write' "
                              "method, required for mode '%s'."
                              % self.mode)

            if (self.mode in ('readonly', 'denywrite') and
                not hasattr(self.__file, 'read')):
                raise IOError("File-like object does not have a 'read' "
                              "method, required for mode %r."
                              % self.mode)

        if isinstance(fileobj, gzip.GzipFile):
            self.compression = 'gzip'
        elif isinstance(fileobj, zipfile.ZipFile):
            # Reading from zip files is supported but not writing (yet)
            self.compression = 'zip'

        if (mode in ('readonly', 'copyonwrite', 'denywrite') or
                (self.compression and mode == 'update')):
            self.readonly = True
        elif (mode == 'ostream' or
                (self.compression and mode == 'append')):
            self.writeonly = True

        # For 'ab+' mode, the pointer is at the end after the open in
        # Linux, but is at the beginning in Solaris.
        if (mode == 'ostream' or self.compression or
            not hasattr(self.__file, 'seek')):
            # For output stream start with a truncated file.
            # For compressed files we can't really guess at the size
            self.size = 0
        else:
            pos = self.__file.tell()
            self.__file.seek(0, 2)
            self.size = self.__file.tell()
            self.__file.seek(pos)

        if self.memmap and not isfile(self.__file):
            self.memmap = False