コード例 #1
0
    def __init__(self, filename, mode='r', bufsize=None, autoUnwrap=False):
        self.__stream = None
        self.__needsVfsClose = False
        self.__reader = None
        self.__writer = None
        self.closed = True
        self.encoding = None
        self.errors = None
        self.__lastWrite = False

        self.mode = mode
        self.name = None
        self.filename = None
        self.newlines = None
        self.softspace = False

        readMode = False
        writeMode = False

        if isinstance(filename, pm.Istream) or isinstance(
                filename, pm.Ostream):
            # If we were given a stream instead of a filename, assign
            # it directly.
            self.__stream = filename
            readMode = isinstance(filename, pm.Istream)
            writeMode = isinstance(filename, pm.Ostream)

        elif isinstance(filename, pm.VirtualFile):
            # We can also "open" a VirtualFile object for reading.
            self.__stream = filename.openReadFile(autoUnwrap)
            if not self.__stream:
                message = 'Could not read virtual file %s' % (repr(filename))
                raise IOError, message
            self.__needsVfsClose = True
            readMode = True

        else:
            # Otherwise, we must have been given a filename.  Open it.
            if isinstance(filename, types.StringTypes):
                # If a raw string is given, assume it's an os-specific
                # filename.
                filename = pm.Filename.fromOsSpecific(filename)
            else:
                # If a Filename is given, make a writable copy anyway.
                filename = pm.Filename(filename)

            self.filename = filename
            self.name = filename.toOsSpecific()

            binary = False
            if 'b' in mode:
                # Strip 'b'.  This means a binary file.
                i = mode.index('b')
                mode = mode[:i] + mode[i + 1:]
                binary = True

            if 'U' in mode:
                # Strip 'U'.  We don't use it; universal-newline support
                # is built into Panda, and can't be changed at runtime.
                i = mode.index('U')
                mode = mode[:i] + mode[i + 1:]
                binary = False

            if mode == '':
                mode = 'r'

            # Per Python docs, we insist this is true.
            assert mode[0] in 'rwa'

            if binary:
                filename.setBinary()
            else:
                filename.setText()

            # Actually open the streams.
            if mode == 'w':
                self.__stream = pm.OFileStream()
                if not filename.openWrite(self.__stream, True):
                    message = 'Could not open %s for writing' % (filename)
                    raise IOError, message
                writeMode = True

            elif mode == 'a':
                self.__stream = pm.OFileStream()
                if not filename.openAppend(self.__stream):
                    message = 'Could not open %s for writing' % (filename)
                    raise IOError, message
                writeMode = True

            elif mode == 'w+':
                self.__stream = pm.FileStream()
                if not filename.openReadWrite(self.__stream, True):
                    message = 'Could not open %s for writing' % (filename)
                    raise IOError, message
                readMode = True
                writeMode = True

            elif mode == 'a+':
                self.__stream = pm.FileStream()
                if not filename.openReadAppend(self.__stream):
                    message = 'Could not open %s for writing' % (filename)
                    raise IOError, message
                readMode = True
                writeMode = True

            elif mode == 'r+':
                self.__stream = pm.FileStream()
                if not filename.exists():
                    message = 'No such file: %s' % (filename)
                    raise IOError, message
                if not filename.openReadWrite(self.__stream, False):
                    message = 'Could not open %s for writing' % (filename)
                    raise IOError, message
                readMode = True
                writeMode = True

            elif mode == 'r':
                # For strictly read mode (not write or read-write
                # mode), we use Panda's VirtualFileSystem.

                self.__stream = _vfs.openReadFile(filename, autoUnwrap)
                if not self.__stream:
                    if not filename.exists():
                        message = 'No such file: %s' % (filename)
                    else:
                        message = 'Could not open %s for reading' % (filename)
                    raise IOError, message
                self.__needsVfsClose = True
                readMode = True

        if readMode:
            self.__reader = pm.StreamReader(self.__stream, False)
        if writeMode:
            self.__writer = pm.StreamWriter(self.__stream, False)
            self.__lastWrite = True