class NumIndex object Огромный спиок строк хранимый текстовом файле По

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
class NumIndex(object):
'''
Огромный спиок строк хранимый в текстовом файле.
Поддерживает доступ к строке по номеру.
'''
def __init__(self, fn, auto_index=True):
self.fn = fn
self.fn_ind = os.path.abspath(self.fn) + '.om.num.index'
self.size = os.stat(self.fn)[6] # получаем размер файла
self.ind_len = len(str(self.size)) # длина индекса
self.old_size = 0
try:
self.load()
except IOError:
pass
if self.size != self.old_size:
# изменился размер файла
if auto_index:
# переиндексация
self.index()
def index(self):
# создаём файл индекса
f_ind = open(self.fn_ind, 'w')
# делаем отступ вначале файла индекса, чтобы было куда
# записать количество строк и размер файла
f_ind.write((' ' * len(str(self.size)) * 2) + ' \n')
# индексируем файл
f = open(self.fn)
self.num_rows = 0
while 1:
ind = str(f.tell())
# дополняем индекс нулями
l = len(ind)
if l < self.ind_len:
ind = '0' * (self.ind_len - l) + ind
f_ind.write(ind)
s = f.readline()
if not s:
break
self.num_rows += 1
f.close()
# добавляем информацию о количестве строк и размере файла
f_ind.seek(0)
f_ind.write(str(self.num_rows) + '\n' + str(self.size))
f_ind.close()
self.load()
def load(self):
# загружаем данные индексного файла
f = open(self.fn_ind)
self.num_rows = int(f.readline())
self.old_size = int(f.readline())
self.start_indent = f.tell()
f.close()
def get(self, n, cnt=1, rstrip=True):
# получаем строки, начиная с заданой
if n >= self.num_rows:
return None
f = open(self.fn)
f.seek(self._get_indent(n))
ret = []
while cnt:
s = f.readline()
if not s:
break
if rstrip:
ret.append(s.rstrip())
else:
ret.append(s)
cnt -= 1
f.close()
return ret
def _get_indent(self, n):
# получаем отступ строки по номеру
f = open(self.fn_ind)
f.seek(self.start_indent + self.ind_len * n)
ret = f.read(self.ind_len)
f.close()
return int(ret)