网站建设怎么用在线资源搜索引擎
任务
需要创建一个输入文件对象(数据可能来自于网络socket 或者其他输入文件句柄),此文件对象允许回退到起点,这样就可以完全读取其中所有数据。
解决方案
将文件对象封装到一个合适的类中:
将文件对象封装到一个合适的类中:
from cStringIO import StringIO
class RewindableFile(obiect):
'''封装一个文件句柄以便重定位到开始位置'''def __init__(self,input_file):#将input_file 封装到一个支持回退的类文件对象中#self.file = input_fileself.buffer_file = StringIO()self.at_start = Truetry :self.start = input_file.tell()except(IOError,AttributeError):self.start = 0self,use_buffer = True
def seek(self,offset,whence = 0):
'''根据给定的字节定位。
必须:whence == 0 and offset == self.start
'''if whence != 0:raise ValueError("whence = %r;expecting 0" %(whence,))if offset != 0raise ValueError("offset = %r;expecting %s" %(offset,self.start))self.rewind()
def rewind(self):'''回到起始位置'''self.buffer_file.seek(0)self.at_start = True
def tell(self):'''返回文件的当前位置(必须在开始处)'''if not self.at_start:raise TypeError("RewindableFile can't tell except at start of file")return self.start
def _read(self,size):if size < 0:#一直读到文件末尾y = self.file.read()if self._use_buffer:self.buffer_file.write(y)return self.buffer_file.read() + yelif size == 0:#不必读空字符串return "x= self.buffer_file.read(size)if len(x) < size:y = self.file.read(size - len(x))if self._use_buffer:self.buffer_file.write(y)return x + yreturn x
def read(self,size = -1):
'''根据size指定的大小读取数据
默认为-1,意味着一直读到文件结束
'''x = self.read(size)if self.at_start and x:self.at_start = Falseself._check_no__buffer()return x
def readline(self):
'''从文件中读取一行'''
# buffer_file中有吗?s =self.buffer_file.readline()if s[-1:] == "\n":return s#没有,从输入文件中读取一行t = self.file.readline()if self._use_buffer:self.buffer_file.write(t)self._check_no_buffer()return s + t
def readlines(self):
'''读取文件中所有剩余的行'''return self.read().splitlines(True)
def _check_no_buffer(self):
#如果"nobuffer"被调用,而且我们也完成了对缓存文件的处理
#那就删掉缓存,把所有的东西都重定向到原来的输入文件if not self._use_buffer and self.buffer_file.tell() == len(self.buffer_file.getvalue()):
#为了获得尽可能高的性能,我们重新绑定了self中的所有相关方法for n in'seek tell read readline readlines',split():setattr(self,n,getattr(self.file,n,None))del self.buffer_file
def nobuffer(self):
'''通知 Rewindablerile,一旦缓存耗尽就停止继续使用缓存'''self._use_buffer = False
讨论
太长了,此处省略。