r"""File-like objects that read from or write to a string buffer.This implements (nearly) all stdio methods.f = StringIO() # ready for writingf = StringIO(buf) # ready for readingf.close() # explicitly release resources heldflag = f.isatty() # always falsepos = f.tell() # get current positionf.seek(pos) # set current positionf.seek(pos, mode) # mode 0: absolute; 1: relative; 2: relative to EOFbuf = f.read() # read until EOFbuf = f.read(n) # read up to n bytesbuf = f.readline() # read until end of line ('\n') or EOFlist = f.readlines()# list of f.readline() results until EOFf.truncate([size]) # truncate file at to at most size (default: current pos)f.write(buf) # write at current positionf.writelines(list) # for line in list: f.write(line)f.getvalue() # return whole file's contents as a stringNotes:- Using a real file is often faster (but less convenient).- There's also a much faster implementation in C, called cStringIO, butit's not subclassable.- fileno() is left unimplemented so that code which uses it triggersan exception early.- Seeking far beyond EOF and then writing will insert real nullbytes that occupy space in the buffer.- There's a simple test set (see end of this file)."""try:from errno import EINVALexcept ImportError:EINVAL = 22__all__ = ["StringIO"]def _complain_ifclosed(closed):if closed:raise ValueError, "I/O operation on closed file"class StringIO:"""class StringIO([buffer])When a StringIO object is created, it can be initialized to an existingstring by passing the string to the constructor. If no string is given,the StringIO will start empty.The StringIO object can accept either Unicode or 8-bit strings, butmixing the two may take some care. If both are used, 8-bit strings thatcannot be interpreted as 7-bit ASCII (that use the 8th bit) will causea UnicodeError to be raised when getvalue() is called."""def __init__(self, buf = ''):# Force self.buf to be a string or unicodeif not isinstance(buf, basestring):buf = str(buf)self.buf = bufself.len = len(buf)self.buflist = []self.pos = 0self.closed = Falseself.softspace = 0def __iter__(self):return selfdef next(self):"""A file object is its own iterator, for example iter(f) returns f(unless f is closed). When a file is used as an iterator, typicallyin a for loop (for example, for line in f: print line), the next()method is called repeatedly. This method returns the next input line,or raises StopIteration when EOF is hit."""_complain_ifclosed(self.closed)r = self.readline()if not r:raise StopIterationreturn rdef close(self):"""Free the memory buffer."""if not self.closed:self.closed = Truedel self.buf, self.posdef isatty(self):"""Returns False because StringIO objects are not connected to atty-like device."""_complain_ifclosed(self.closed)return Falsedef seek(self, pos, mode = 0):"""Set the file's current position.The mode argument is optional and defaults to 0 (absolute filepositioning); other values are 1 (seek relative to the currentposition) and 2 (seek relative to the file's end).There is no return value."""_complain_ifclosed(self.closed)if self.buflist:self.buf += ''.join(self.buflist)self.buflist = []if mode == 1:pos += self.poselif mode == 2:pos += self.lenself.pos = max(0, pos)def tell(self):"""Return the file's current position."""_complain_ifclosed(self.closed)return self.posdef read(self, n = -1):"""Read at most size bytes from the file(less if the read hits EOF before obtaining size bytes).If the size argument is negative or omitted, read all data until EOFis reached. The bytes are returned as a string object. An emptystring is returned when EOF is encountered immediately."""_complain_ifclosed(self.closed)if self.buflist:self.buf += ''.join(self.buflist)self.buflist = []if n < 0:newpos = self.lenelse:newpos = min(self.pos+n, self.len)r = self.buf[self.pos:newpos]self.pos = newposreturn rdef readline(self, length=None):r"""Read one entire line from the file.A trailing newline character is kept in the string (but may be absentwhen a file ends with an incomplete line). If the size argument ispresent and non-negative, it is a maximum byte count (including thetrailing newline) and an incomplete line may be returned.An empty string is returned only when EOF is encountered immediately.Note: Unlike stdio's fgets(), the returned string contains nullcharacters ('0円') if they occurred in the input."""_complain_ifclosed(self.closed)if self.buflist:self.buf += ''.join(self.buflist)self.buflist = []i = self.buf.find('\n', self.pos)if i < 0:newpos = self.lenelse:newpos = i+1if length is not None:if self.pos + length < newpos:newpos = self.pos + lengthr = self.buf[self.pos:newpos]self.pos = newposreturn rdef readlines(self, sizehint = 0):"""Read until EOF using readline() and return a list containing thelines thus read.If the optional sizehint argument is present, instead of reading upto EOF, whole lines totalling approximately sizehint bytes (or moreto accommodate a final whole line)."""total = 0lines = []line = self.readline()while line:lines.append(line)total += len(line)if 0 < sizehint <= total:breakline = self.readline()return linesdef truncate(self, size=None):"""Truncate the file's size.If the optional size argument is present, the file is truncated to(at most) that size. The size defaults to the current position.The current file position is not changed unless the positionis beyond the new file size.If the specified size exceeds the file's current size, thefile remains unchanged."""_complain_ifclosed(self.closed)if size is None:size = self.poselif size < 0:raise IOError(EINVAL, "Negative size not allowed")elif size < self.pos:self.pos = sizeself.buf = self.getvalue()[:size]self.len = sizedef write(self, s):"""Write a string to the file.There is no return value."""_complain_ifclosed(self.closed)if not s: return# Force s to be a string or unicodeif not isinstance(s, basestring):s = str(s)spos = self.posslen = self.lenif spos == slen:self.buflist.append(s)self.len = self.pos = spos + len(s)returnif spos > slen:self.buflist.append('0円'*(spos - slen))slen = sposnewpos = spos + len(s)if spos < slen:if self.buflist:self.buf += ''.join(self.buflist)self.buflist = [self.buf[:spos], s, self.buf[newpos:]]self.buf = ''if newpos > slen:slen = newposelse:self.buflist.append(s)slen = newposself.len = slenself.pos = newposdef writelines(self, iterable):"""Write a sequence of strings to the file. The sequence can be anyiterable object producing strings, typically a list of strings. Thereis no return value.(The name is intended to match readlines(); writelines() does not addline separators.)"""write = self.writefor line in iterable:write(line)def flush(self):"""Flush the internal buffer"""_complain_ifclosed(self.closed)def getvalue(self):"""Retrieve the entire contents of the "file" at any time beforethe StringIO object's close() method is called.The StringIO object can accept either Unicode or 8-bit strings,but mixing the two may take some care. If both are used, 8-bitstrings that cannot be interpreted as 7-bit ASCII (that use the8th bit) will cause a UnicodeError to be raised when getvalue()is called."""if self.buflist:self.buf += ''.join(self.buflist)self.buflist = []return self.buf# A little test suitedef test():import sysif sys.argv[1:]:file = sys.argv[1]else:file = '/etc/passwd'lines = open(file, 'r').readlines()text = open(file, 'r').read()f = StringIO()for line in lines[:-2]:f.write(line)f.writelines(lines[-2:])if f.getvalue() != text:raise RuntimeError, 'write failed'length = f.tell()print 'File length =', lengthf.seek(len(lines[0]))f.write(lines[1])f.seek(0)print 'First line =', repr(f.readline())print 'Position =', f.tell()line = f.readline()print 'Second line =', repr(line)f.seek(-len(line), 1)line2 = f.read(len(line))if line != line2:raise RuntimeError, 'bad result after seek back'f.seek(len(line2), 1)list = f.readlines()line = list[-1]f.seek(f.tell() - len(line))line2 = f.read()if line != line2:raise RuntimeError, 'bad result after seek back from EOF'print 'Read', len(list), 'more lines'print 'File length =', f.tell()if f.tell() != length:raise RuntimeError, 'bad length'f.truncate(length/2)f.seek(0, 2)print 'Truncated length =', f.tell()if f.tell() != length/2:raise RuntimeError, 'truncate did not adjust length'f.close()if __name__ == '__main__':test()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。