python settings模块_Python学习之路10——Python常用模块

classTarFile(object):"""The TarFile Class provides an interface to tar archives."""debug= 0 #May be set from 0 (no msgs) to 3 (all msgs)

dereference= False #If true, add content of linked file to the

#tar file, else the link.

ignore_zeros= False #If true, skips empty or invalid blocks and

#continues processing.

errorlevel= 1 #If 0, fatal errors only appear in debug

#messages (if debug >= 0). If > 0, errors

#are passed to the caller as exceptions.

format= DEFAULT_FORMAT #The format to use when creating an archive.

encoding= ENCODING #Encoding for 8-bit character strings.

errors= None #Error handler for unicode conversion.

tarinfo= TarInfo #The default TarInfo class to use.

fileobject= ExFileObject #The default ExFileObject class to use.

def __init__(self, name=None, mode="r", fileobj=None, format=None,

tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,

errors=None, pax_headers=None, debug=None, errorlevel=None):"""Open an (uncompressed) tar archive `name'. `mode' is either 'r' to

read from an existing archive, 'a' to append data to an existing

file or 'w' to create a new file overwriting an existing one. `mode'

defaults to 'r'.

If `fileobj' is given, it is used for reading or writing data. If it

can be determined, `mode' is overridden by `fileobj's mode.

`fileobj' is not closed, when TarFile is closed."""modes= {"r": "rb", "a": "r+b", "w": "wb"}if mode not inmodes:raise ValueError("mode must be 'r', 'a' or 'w'")

self.mode=mode

self._mode=modes[mode]if notfileobj:if self.mode == "a" and notos.path.exists(name):#Create nonexistent files in append mode.

self.mode = "w"self._mode= "wb"fileobj=bltn_open(name, self._mode)

self._extfileobj=Falseelse:if name is None and hasattr(fileobj, "name"):

name=fileobj.nameif hasattr(fileobj, "mode"):

self._mode=fileobj.mode

self._extfileobj=True

self.name= os.path.abspath(name) if name elseNone

self.fileobj=fileobj#Init attributes.

if format is notNone:

self.format=formatif tarinfo is notNone:

self.tarinfo=tarinfoif dereference is notNone:

self.dereference=dereferenceif ignore_zeros is notNone:

self.ignore_zeros=ignore_zerosif encoding is notNone:

self.encoding=encodingif errors is notNone:

self.errors=errorselif mode == "r":

self.errors= "utf-8"

else:

self.errors= "strict"

if pax_headers is not None and self.format ==PAX_FORMAT:

self.pax_headers=pax_headerselse:

self.pax_headers={}if debug is notNone:

self.debug=debugif errorlevel is notNone:

self.errorlevel=errorlevel#Init datastructures.

self.closed =False

self.members= [] #list of members as TarInfo objects

self._loaded = False #flag if all members have been read

self.offset =self.fileobj.tell()#current position in the archive file

self.inodes = {} #dictionary caching the inodes of

#archive members already added

try:if self.mode == "r":

self.firstmember=None

self.firstmember=self.next()if self.mode == "a":#Move to the end of the archive,

#before the first empty block.

whileTrue:

self.fileobj.seek(self.offset)try:

tarinfo=self.tarinfo.fromtarfile(self)

self.members.append(tarinfo)exceptEOFHeaderError:

self.fileobj.seek(self.offset)break

exceptHeaderError, e:raiseReadError(str(e))if self.mode in "aw":

self._loaded=Trueifself.pax_headers:

buf=self.tarinfo.create_pax_global_header(self.pax_headers.copy())

self.fileobj.write(buf)

self.offset+=len(buf)except:if notself._extfileobj:

self.fileobj.close()

self.closed=Trueraise

def_getposix(self):return self.format ==USTAR_FORMATdef_setposix(self, value):importwarnings

warnings.warn("use the format attribute instead", DeprecationWarning,2)ifvalue:

self.format=USTAR_FORMATelse:

self.format=GNU_FORMAT

posix=property(_getposix, _setposix)#--------------------------------------------------------------------------

#Below are the classmethods which act as alternate constructors to the

#TarFile class. The open() method is the only one that is needed for

#public use; it is the "super"-constructor and is able to select an

#adequate "sub"-constructor for a particular compression using the mapping

#from OPEN_METH.

# #This concept allows one to subclass TarFile without losing the comfort of

#the super-constructor. A sub-constructor is registered and made available

#by adding it to the mapping in OPEN_METH.

@classmethoddef open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs):"""Open a tar archive for reading, writing or appending. Return

an appropriate TarFile class.

mode:

'r' or 'r:*' open for reading with transparent compression

'r:' open for reading exclusively uncompressed

'r:gz' open for reading with gzip compression

'r:bz2' open for reading with bzip2 compression

'a' or 'a:' open for appending, creating the file if necessary

'w' or 'w:' open for writing without compression

'w:gz' open for writing with gzip compression

'w:bz2' open for writing with bzip2 compression

'r|*' open a stream of tar blocks with transparent compression

'r|' open an uncompressed stream of tar blocks for reading

'r|gz' open a gzip compressed stream of tar blocks

'r|bz2' open a bzip2 compressed stream of tar blocks

'w|' open an uncompressed stream for writing

'w|gz' open a gzip compressed stream for writing

'w|bz2' open a bzip2 compressed stream for writing"""

if not name and notfileobj:raise ValueError("nothing to open")if mode in ("r", "r:*"):#Find out which *open() is appropriate for opening the file.

for comptype incls.OPEN_METH:

func=getattr(cls, cls.OPEN_METH[comptype])if fileobj is notNone:

saved_pos=fileobj.tell()try:return func(name, "r", fileobj, **kwargs)except(ReadError, CompressionError), e:if fileobj is notNone:

fileobj.seek(saved_pos)continue

raise ReadError("file could not be opened successfully")elif ":" inmode:

filemode, comptype= mode.split(":", 1)

filemode= filemode or "r"comptype= comptype or "tar"

#Select the *open() function according to

#given compression.

if comptype incls.OPEN_METH:

func=getattr(cls, cls.OPEN_METH[comptype])else:raise CompressionError("unknown compression type %r" %comptype)return func(name, filemode, fileobj, **kwargs)elif "|" inmode:

filemode, comptype= mode.split("|", 1)

filemode= filemode or "r"comptype= comptype or "tar"

if filemode not in ("r", "w"):raise ValueError("mode must be 'r' or 'w'")

stream=_Stream(name, filemode, comptype, fileobj, bufsize)try:

t= cls(name, filemode, stream, **kwargs)except:

stream.close()raiset._extfileobj=Falsereturntelif mode in ("a", "w"):return cls.taropen(name, mode, fileobj, **kwargs)raise ValueError("undiscernible mode")

@classmethoddef taropen(cls, name, mode="r", fileobj=None, **kwargs):"""Open uncompressed tar archive name for reading or writing."""

if mode not in ("r", "a", "w"):raise ValueError("mode must be 'r', 'a' or 'w'")return cls(name, mode, fileobj, **kwargs)

@classmethoddef gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):"""Open gzip compressed tar archive name for reading or writing.

Appending is not allowed."""

if mode not in ("r", "w"):raise ValueError("mode must be 'r' or 'w'")try:importgzip

gzip.GzipFileexcept(ImportError, AttributeError):raise CompressionError("gzip module is not available")try:

fileobj=gzip.GzipFile(name, mode, compresslevel, fileobj)exceptOSError:if fileobj is not None and mode == 'r':raise ReadError("not a gzip file")raise

try:

t= cls.taropen(name, mode, fileobj, **kwargs)exceptIOError:

fileobj.close()if mode == 'r':raise ReadError("not a gzip file")raise

except:

fileobj.close()raiset._extfileobj=Falsereturnt

@classmethoddef bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):"""Open bzip2 compressed tar archive name for reading or writing.

Appending is not allowed."""

if mode not in ("r", "w"):raise ValueError("mode must be 'r' or 'w'.")try:importbz2exceptImportError:raise CompressionError("bz2 module is not available")if fileobj is notNone:

fileobj=_BZ2Proxy(fileobj, mode)else:

fileobj= bz2.BZ2File(name, mode, compresslevel=compresslevel)try:

t= cls.taropen(name, mode, fileobj, **kwargs)except(IOError, EOFError):

fileobj.close()if mode == 'r':raise ReadError("not a bzip2 file")raise

except:

fileobj.close()raiset._extfileobj=Falsereturnt#All *open() methods are registered here.

OPEN_METH ={"tar": "taropen", #uncompressed tar

"gz": "gzopen", #gzip compressed tar

"bz2": "bz2open" #bzip2 compressed tar

}#--------------------------------------------------------------------------

#The public methods which TarFile provides:

defclose(self):"""Close the TarFile. In write-mode, two finishing zero blocks are

appended to the archive."""

ifself.closed:return

if self.mode in "aw":

self.fileobj.write(NUL* (BLOCKSIZE * 2))

self.offset+= (BLOCKSIZE * 2)#fill up the end with zero-blocks

#(like option -b20 for tar does)

blocks, remainder =divmod(self.offset, RECORDSIZE)if remainder >0:

self.fileobj.write(NUL* (RECORDSIZE -remainder))if notself._extfileobj:

self.fileobj.close()

self.closed=Truedefgetmember(self, name):"""Return a TarInfo object for member `name'. If `name' can not be

found in the archive, KeyError is raised. If a member occurs more

than once in the archive, its last occurrence is assumed to be the

most up-to-date version."""tarinfo=self._getmember(name)if tarinfo isNone:raise KeyError("filename %r not found" %name)returntarinfodefgetmembers(self):"""Return the members of the archive as a list of TarInfo objects. The

list has the same order as the members in the archive."""self._check()if not self._loaded: #if we want to obtain a list of

self._load() #all members, we first have to

#scan the whole archive.

returnself.membersdefgetnames(self):"""Return the members of the archive as a list of their names. It has

the same order as the list returned by getmembers()."""

return [tarinfo.name for tarinfo inself.getmembers()]def gettarinfo(self, name=None, arcname=None, fileobj=None):"""Create a TarInfo object for either the file `name' or the file

object `fileobj' (using os.fstat on its file descriptor). You can

modify some of the TarInfo's attributes before you add it using

addfile(). If given, `arcname' specifies an alternative name for the

file in the archive."""self._check("aw")#When fileobj is given, replace name by

#fileobj's real name.

if fileobj is notNone:

name=fileobj.name#Building the name of the member in the archive.

#Backward slashes are converted to forward slashes,

#Absolute paths are turned to relative paths.

if arcname isNone:

arcname=name

drv, arcname=os.path.splitdrive(arcname)

arcname= arcname.replace(os.sep, "/")

arcname= arcname.lstrip("/")#Now, fill the TarInfo object with

#information specific for the file.

tarinfo =self.tarinfo()

tarinfo.tarfile=self#Use os.stat or os.lstat, depending on platform

#and if symlinks shall be resolved.

if fileobj isNone:if hasattr(os, "lstat") and notself.dereference:

statres=os.lstat(name)else:

statres=os.stat(name)else:

statres=os.fstat(fileobj.fileno())

linkname= ""stmd=statres.st_modeifstat.S_ISREG(stmd):

inode=(statres.st_ino, statres.st_dev)if not self.dereference and statres.st_nlink > 1 and\

inodein self.inodes and arcname !=self.inodes[inode]:#Is it a hardlink to an already

#archived file?

type =LNKTYPE

linkname=self.inodes[inode]else:#The inode is added only if its valid.

#For win32 it is always 0.

type =REGTYPEifinode[0]:

self.inodes[inode]=arcnameelifstat.S_ISDIR(stmd):

type=DIRTYPEelifstat.S_ISFIFO(stmd):

type=FIFOTYPEelifstat.S_ISLNK(stmd):

type=SYMTYPE

linkname=os.readlink(name)elifstat.S_ISCHR(stmd):

type=CHRTYPEelifstat.S_ISBLK(stmd):

type=BLKTYPEelse:returnNone#Fill the TarInfo object with all

#information we can get.

tarinfo.name =arcname

tarinfo.mode=stmd

tarinfo.uid=statres.st_uid

tarinfo.gid=statres.st_gidif type ==REGTYPE:

tarinfo.size=statres.st_sizeelse:

tarinfo.size=0L

tarinfo.mtime=statres.st_mtime

tarinfo.type=type

tarinfo.linkname=linknameifpwd:try:

tarinfo.uname=pwd.getpwuid(tarinfo.uid)[0]exceptKeyError:pass

ifgrp:try:

tarinfo.gname=grp.getgrgid(tarinfo.gid)[0]exceptKeyError:pass

if type in(CHRTYPE, BLKTYPE):if hasattr(os, "major") and hasattr(os, "minor"):

tarinfo.devmajor=os.major(statres.st_rdev)

tarinfo.devminor=os.minor(statres.st_rdev)returntarinfodef list(self, verbose=True):"""Print a table of contents to sys.stdout. If `verbose' is False, only

the names of the members are printed. If it is True, an `ls -l'-like

output is produced."""self._check()for tarinfo inself:ifverbose:printfilemode(tarinfo.mode),print "%s/%s" % (tarinfo.uname ortarinfo.uid,

tarinfo.gnameortarinfo.gid),if tarinfo.ischr() ortarinfo.isblk():print "%10s" % ("%d,%d"\%(tarinfo.devmajor, tarinfo.devminor)),else:print "%10d" %tarinfo.size,print "%d-%02d-%02d %02d:%02d:%02d"\% time.localtime(tarinfo.mtime)[:6],print tarinfo.name + ("/" if tarinfo.isdir() else ""),ifverbose:iftarinfo.issym():print "->", tarinfo.linkname,iftarinfo.islnk():print "link to", tarinfo.linkname,print

def add(self, name, arcname=None, recursive=True, exclude=None, filter=None):"""Add the file `name' to the archive. `name' may be any type of file

(directory, fifo, symbolic link, etc.). If given, `arcname'

specifies an alternative name for the file in the archive.

Directories are added recursively by default. This can be avoided by

setting `recursive' to False. `exclude' is a function that should

return True for each filename to be excluded. `filter' is a function

that expects a TarInfo object argument and returns the changed

TarInfo object, if it returns None the TarInfo object will be

excluded from the archive."""self._check("aw")if arcname isNone:

arcname=name#Exclude pathnames.

if exclude is notNone:importwarnings

warnings.warn("use the filter argument instead",

DeprecationWarning,2)ifexclude(name):

self._dbg(2, "tarfile: Excluded %r" %name)return

#Skip if somebody tries to archive the archive...

if self.name is not None and os.path.abspath(name) ==self.name:

self._dbg(2, "tarfile: Skipped %r" %name)returnself._dbg(1, name)#Create a TarInfo object from the file.

tarinfo =self.gettarinfo(name, arcname)if tarinfo isNone:

self._dbg(1, "tarfile: Unsupported type %r" %name)return

#Change or exclude the TarInfo object.

if filter is notNone:

tarinfo=filter(tarinfo)if tarinfo isNone:

self._dbg(2, "tarfile: Excluded %r" %name)return

#Append the tar header and data to the archive.

iftarinfo.isreg():

with bltn_open(name,"rb") as f:

self.addfile(tarinfo, f)eliftarinfo.isdir():

self.addfile(tarinfo)ifrecursive:for f inos.listdir(name):

self.add(os.path.join(name, f), os.path.join(arcname, f),

recursive, exclude, filter)else:

self.addfile(tarinfo)def addfile(self, tarinfo, fileobj=None):"""Add the TarInfo object `tarinfo' to the archive. If `fileobj' is

given, tarinfo.size bytes are read from it and added to the archive.

You can create TarInfo objects using gettarinfo().

On Windows platforms, `fileobj' should always be opened with mode

'rb' to avoid irritation about the file size."""self._check("aw")

tarinfo=copy.copy(tarinfo)

buf=tarinfo.tobuf(self.format, self.encoding, self.errors)

self.fileobj.write(buf)

self.offset+=len(buf)#If there's data to follow, append it.

if fileobj is notNone:

copyfileobj(fileobj, self.fileobj, tarinfo.size)

blocks, remainder=divmod(tarinfo.size, BLOCKSIZE)if remainder >0:

self.fileobj.write(NUL* (BLOCKSIZE -remainder))

blocks+= 1self.offset+= blocks *BLOCKSIZE

self.members.append(tarinfo)def extractall(self, path=".", members=None):"""Extract all members from the archive to the current working

directory and set owner, modification time and permissions on

directories afterwards. `path' specifies a different directory

to extract to. `members' is optional and must be a subset of the

list returned by getmembers()."""directories=[]if members isNone:

members=selffor tarinfo inmembers:iftarinfo.isdir():#Extract directories with a safe mode.

directories.append(tarinfo)

tarinfo=copy.copy(tarinfo)

tarinfo.mode= 0700self.extract(tarinfo, path)#Reverse sort directories.

directories.sort(key=operator.attrgetter('name'))

directories.reverse()#Set correct owner, mtime and filemode on directories.

for tarinfo indirectories:

dirpath=os.path.join(path, tarinfo.name)try:

self.chown(tarinfo, dirpath)

self.utime(tarinfo, dirpath)

self.chmod(tarinfo, dirpath)exceptExtractError, e:if self.errorlevel > 1:raise

else:

self._dbg(1, "tarfile: %s" %e)def extract(self, member, path=""):"""Extract a member from the archive to the current working directory,

using its full name. Its file information is extracted as accurately

as possible. `member' may be a filename or a TarInfo object. You can

specify a different directory using `path'."""self._check("r")ifisinstance(member, basestring):

tarinfo=self.getmember(member)else:

tarinfo=member#Prepare the link target for makelink().

iftarinfo.islnk():

tarinfo._link_target=os.path.join(path, tarinfo.linkname)try:

self._extract_member(tarinfo, os.path.join(path, tarinfo.name))exceptEnvironmentError, e:if self.errorlevel >0:raise

else:if e.filename isNone:

self._dbg(1, "tarfile: %s" %e.strerror)else:

self._dbg(1, "tarfile: %s %r" %(e.strerror, e.filename))exceptExtractError, e:if self.errorlevel > 1:raise

else:

self._dbg(1, "tarfile: %s" %e)defextractfile(self, member):"""Extract a member from the archive as a file object. `member' may be

a filename or a TarInfo object. If `member' is a regular file, a

file-like object is returned. If `member' is a link, a file-like

object is constructed from the link's target. If `member' is none of

the above, None is returned.

The file-like object is read-only and provides the following

methods: read(), readline(), readlines(), seek() and tell()"""self._check("r")ifisinstance(member, basestring):

tarinfo=self.getmember(member)else:

tarinfo=memberiftarinfo.isreg():returnself.fileobject(self, tarinfo)elif tarinfo.type not inSUPPORTED_TYPES:#If a member's type is unknown, it is treated as a

#regular file.

returnself.fileobject(self, tarinfo)elif tarinfo.islnk() ortarinfo.issym():ifisinstance(self.fileobj, _Stream):#A small but ugly workaround for the case that someone tries

#to extract a (sym)link as a file-object from a non-seekable

#stream of tar blocks.

raise StreamError("cannot extract (sym)link as file object")else:#A (sym)link's file object is its target's file object.

returnself.extractfile(self._find_link_target(tarinfo))else:#If there's no data associated with the member (directory, chrdev,

#blkdev, etc.), return None instead of a file object.

returnNonedef_extract_member(self, tarinfo, targetpath):"""Extract the TarInfo object tarinfo to a physical

file called targetpath."""

#Fetch the TarInfo object for the given name

#and build the destination pathname, replacing

#forward slashes to platform specific separators.

targetpath = targetpath.rstrip("/")

targetpath= targetpath.replace("/", os.sep)#Create all upper directories.

upperdirs =os.path.dirname(targetpath)if upperdirs and notos.path.exists(upperdirs):#Create directories that are not part of the archive with

#default permissions.

os.makedirs(upperdirs)if tarinfo.islnk() ortarinfo.issym():

self._dbg(1, "%s -> %s" %(tarinfo.name, tarinfo.linkname))else:

self._dbg(1, tarinfo.name)iftarinfo.isreg():

self.makefile(tarinfo, targetpath)eliftarinfo.isdir():

self.makedir(tarinfo, targetpath)eliftarinfo.isfifo():

self.makefifo(tarinfo, targetpath)elif tarinfo.ischr() ortarinfo.isblk():

self.makedev(tarinfo, targetpath)elif tarinfo.islnk() ortarinfo.issym():

self.makelink(tarinfo, targetpath)elif tarinfo.type not inSUPPORTED_TYPES:

self.makeunknown(tarinfo, targetpath)else:

self.makefile(tarinfo, targetpath)

self.chown(tarinfo, targetpath)if nottarinfo.issym():

self.chmod(tarinfo, targetpath)

self.utime(tarinfo, targetpath)#--------------------------------------------------------------------------

#Below are the different file methods. They are called via

#_extract_member() when extract() is called. They can be replaced in a

#subclass to implement other functionality.

defmakedir(self, tarinfo, targetpath):"""Make a directory called targetpath."""

try:#Use a safe mode for the directory, the real mode is set

#later in _extract_member().

os.mkdir(targetpath, 0700)exceptEnvironmentError, e:if e.errno !=errno.EEXIST:raise

defmakefile(self, tarinfo, targetpath):"""Make a file called targetpath."""source=self.extractfile(tarinfo)try:

with bltn_open(targetpath,"wb") as target:

copyfileobj(source, target)finally:

source.close()defmakeunknown(self, tarinfo, targetpath):"""Make a file from a TarInfo object with an unknown type

at targetpath."""self.makefile(tarinfo, targetpath)

self._dbg(1, "tarfile: Unknown file type %r,"\"extracted as regular file." %tarinfo.type)defmakefifo(self, tarinfo, targetpath):"""Make a fifo called targetpath."""

if hasattr(os, "mkfifo"):

os.mkfifo(targetpath)else:raise ExtractError("fifo not supported by system")defmakedev(self, tarinfo, targetpath):"""Make a character or block device called targetpath."""

if not hasattr(os, "mknod") or not hasattr(os, "makedev"):raise ExtractError("special devices not supported by system")

mode=tarinfo.modeiftarinfo.isblk():

mode|=stat.S_IFBLKelse:

mode|=stat.S_IFCHR

os.mknod(targetpath, mode,

os.makedev(tarinfo.devmajor, tarinfo.devminor))defmakelink(self, tarinfo, targetpath):"""Make a (symbolic) link called targetpath. If it cannot be created

(platform limitation), we try to make a copy of the referenced file

instead of a link."""

if hasattr(os, "symlink") and hasattr(os, "link"):#For systems that support symbolic and hard links.

iftarinfo.issym():ifos.path.lexists(targetpath):

os.unlink(targetpath)

os.symlink(tarinfo.linkname, targetpath)else:#See extract().

ifos.path.exists(tarinfo._link_target):ifos.path.lexists(targetpath):

os.unlink(targetpath)

os.link(tarinfo._link_target, targetpath)else:

self._extract_member(self._find_link_target(tarinfo), targetpath)else:try:

self._extract_member(self._find_link_target(tarinfo), targetpath)exceptKeyError:raise ExtractError("unable to resolve link inside archive")defchown(self, tarinfo, targetpath):"""Set owner of targetpath according to tarinfo."""

if pwd and hasattr(os, "geteuid") and os.geteuid() ==0:#We have to be root to do so.

try:

g= grp.getgrnam(tarinfo.gname)[2]exceptKeyError:

g=tarinfo.gidtry:

u= pwd.getpwnam(tarinfo.uname)[2]exceptKeyError:

u=tarinfo.uidtry:if tarinfo.issym() and hasattr(os, "lchown"):

os.lchown(targetpath, u, g)else:if sys.platform != "os2emx":

os.chown(targetpath, u, g)exceptEnvironmentError, e:raise ExtractError("could not change owner")defchmod(self, tarinfo, targetpath):"""Set file permissions of targetpath according to tarinfo."""

if hasattr(os, 'chmod'):try:

os.chmod(targetpath, tarinfo.mode)exceptEnvironmentError, e:raise ExtractError("could not change mode")defutime(self, tarinfo, targetpath):"""Set modification time of targetpath according to tarinfo."""

if not hasattr(os, 'utime'):return

try:

os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))exceptEnvironmentError, e:raise ExtractError("could not change modification time")#--------------------------------------------------------------------------

defnext(self):"""Return the next member of the archive as a TarInfo object, when

TarFile is opened for reading. Return None if there is no more

available."""self._check("ra")if self.firstmember is notNone:

m=self.firstmember

self.firstmember=Nonereturnm#Read the next block.

self.fileobj.seek(self.offset)

tarinfo=NonewhileTrue:try:

tarinfo=self.tarinfo.fromtarfile(self)exceptEOFHeaderError, e:ifself.ignore_zeros:

self._dbg(2, "0x%X: %s" %(self.offset, e))

self.offset+=BLOCKSIZEcontinue

exceptInvalidHeaderError, e:ifself.ignore_zeros:

self._dbg(2, "0x%X: %s" %(self.offset, e))

self.offset+=BLOCKSIZEcontinue

elif self.offset ==0:raiseReadError(str(e))exceptEmptyHeaderError:if self.offset ==0:raise ReadError("empty file")exceptTruncatedHeaderError, e:if self.offset ==0:raiseReadError(str(e))exceptSubsequentHeaderError, e:raiseReadError(str(e))break

if tarinfo is notNone:

self.members.append(tarinfo)else:

self._loaded=Truereturntarinfo#--------------------------------------------------------------------------

#Little helper methods:

def _getmember(self, name, tarinfo=None, normalize=False):"""Find an archive member by name from bottom to top.

If tarinfo is given, it is used as the starting point."""

#Ensure that all members have been loaded.

members =self.getmembers()#Limit the member search list up to tarinfo.

if tarinfo is notNone:

members=members[:members.index(tarinfo)]ifnormalize:

name=os.path.normpath(name)for member inreversed(members):ifnormalize:

member_name=os.path.normpath(member.name)else:

member_name=member.nameif name ==member_name:returnmemberdef_load(self):"""Read through the entire archive file and look for readable

members."""

whileTrue:

tarinfo=self.next()if tarinfo isNone:breakself._loaded=Truedef _check(self, mode=None):"""Check if TarFile is still open, and if the operation's mode

corresponds to TarFile's mode."""

ifself.closed:raise IOError("%s is closed" % self.__class__.__name__)if mode is not None and self.mode not inmode:raise IOError("bad operation for mode %r" %self.mode)def_find_link_target(self, tarinfo):"""Find the target member of a symlink or hardlink member in the

archive."""

iftarinfo.issym():#Always search the entire archive.

linkname = "/".join(filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname)))

limit=Noneelse:#Search the archive before the link, because a hard link is

#just a reference to an already archived file.

linkname =tarinfo.linkname

limit=tarinfo

member= self._getmember(linkname, tarinfo=limit, normalize=True)if member isNone:raise KeyError("linkname %r not found" %linkname)returnmemberdef __iter__(self):"""Provide an iterator object."""

ifself._loaded:returniter(self.members)else:returnTarIter(self)def_dbg(self, level, msg):"""Write debugging output to sys.stderr."""

if level <=self.debug:print >>sys.stderr, msgdef __enter__(self):

self._check()returnselfdef __exit__(self, type, value, traceback):if type isNone:

self.close()else:#An exception occurred. We must not call close() because

#it would try to write end-of-archive blocks and padding.

if notself._extfileobj:

self.fileobj.close()

self.closed=True#class TarFile

TarFile

TarFile 源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值