Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1130181
  • 博文数量: 170
  • 博客积分: 1603
  • 博客等级: 上尉
  • 技术积分: 1897
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-09 15:54
文章分类

全部博文(170)

文章存档

2016年(27)

2015年(21)

2014年(27)

2013年(21)

2012年(7)

2011年(67)

我的朋友

分类: 系统运维

2016-03-11 20:40:58

网上找的都不太好

自己写了个 模仿tail


更新了下代码, 发现windows和unix文本区别还是会导致点坑的


点击(此处)折叠或打开

  1. def get_last_line(file_path, max_line_number, buffer_size=4096):
  2.     # 从末尾读取文件并返回以行组成的列表
  3.     """
  4.     :param file_path: 文件路径
  5.     :param max_line_number: 返回行数
  6.     :param buffer_size: 读缓冲区大小
  7.     :return: :raise ParameterIllegal: 自定义错误
  8.     """
  9.     if not isinstance(max_line_number, (int, long)):
  10.         raise ParameterIllegal('max line number not int')
  11.     if not isinstance(file_path, str):
  12.         raise ParameterIllegal('file_path value error')
  13.     if not isinstance(buffer_size, (int, long)):
  14.         raise ParameterIllegal('buffer_size not int')
  15.     if not os.path.exists(file_path):
  16.         raise ParameterIllegal('file_path not exists')
  17.     if buffer_size > 20000:
  18.         raise ParameterIllegal('buffer_size large then 20000')
  19.     # 限制最大读取行数
  20.     if max_line_number > 100:
  21.         max_line_number = 100
  22.     out_put_line_list = []
  23.     try:
  24.         # 非unix文件使用r方式打开读取长度会减少,直接以rb方式打开
  25.         f = open(file_path, 'rb', buffering=buffer_size)
  26.     except OSError:
  27.         raise ParameterIllegal('open file get os error')
  28.     except IOError:
  29.         raise ParameterIllegal('open file get io error')
  30.     # 文件大小
  31.     file_size = os.path.getsize(file_path)
  32.     if file_size == 0:
  33.         try:
  34.             f.close()
  35.             msg = 'closed file'
  36.         except OSError:
  37.             msg = 'close file os error'
  38.         except IOError:
  39.             msg = 'close file io error'
  40.         raise ParameterIllegal('file size is 0 %s' % msg)
  41.     # 当前位置,即开始读取的位置
  42.     if file_size < buffer_size:
  43.         start_read_pos = 0
  44.         buffer_size = file_size
  45.     else:
  46.         start_read_pos = file_size - 1 - buffer_size
  47.     # 实际读取的buffer大小
  48.     read_buffer_size = buffer_size
  49.     # 实际读取到的行数
  50.     read_line_num = 0
  51.     # 未满行的字符串
  52.     line_buffer = ''
  53.     # 全部读取大小
  54.     size_read = 0
  55.     while read_line_num < max_line_number:
  56.         # 已经是文件的最开始部位,设置退出
  57.         # 防止读取过多内容,限制为1M
  58.         size_read += read_buffer_size
  59.         if size_read >= 1048576:
  60.             try:
  61.                 f.close()
  62.                 msg = 'closed file'
  63.             except OSError:
  64.                 msg = 'close file os error'
  65.             except IOError:
  66.                 msg = 'close file io error'
  67.             try:
  68.                 f.close()
  69.             except OSError:
  70.                 raise ParameterIllegal('close file get os error')
  71.             except IOError:
  72.                 raise ParameterIllegal('close file get io error')
  73.             raise ParameterIllegal('read file get string to much long %d, %s' % (size_read, msg))
  74.         # seek到读取位置
  75.         f.seek(start_read_pos)
  76.         # 读取文件
  77.         try:
  78.             string_buffer = f.read(read_buffer_size)
  79.         except OSError:
  80.             try:
  81.                 f.close()
  82.                 msg = 'closed file'
  83.             except OSError:
  84.                 msg = 'close file os error'
  85.             except IOError:
  86.                 msg = 'close file io error'
  87.             raise ParameterIllegal('read file get os error and %s' % msg)
  88.         except IOError:
  89.             try:
  90.                 f.close()
  91.                 msg = 'closed file'
  92.             except OSError:
  93.                 msg = 'close file os error'
  94.             except IOError:
  95.                 msg = 'close file io error'
  96.             raise ParameterIllegal('read file get io error and %s' % msg)
  97.         # 换行位置,默认为string_buffer的结尾
  98.         new_line_pos = read_buffer_size
  99.         # xrange倒序
  100.         for i in xrange(read_buffer_size - 1, -1, -1):
  101.             if string_buffer[i] == '\n':
  102.                  # 切片添加
  103.                 if len(line_buffer) > 0:
  104.                     out_put_line_list.insert(0, string_buffer[i + 1: new_line_pos] + line_buffer)
  105.                     line_buffer = ''
  106.                 else:
  107.                     if len(string_buffer[i + 1: new_line_pos]) > 0:
  108.                         out_put_line_list.insert(0, string_buffer[i + 1: new_line_pos])
  109.                 read_line_num += 1
  110.                 new_line_pos = i
  111.                 if read_line_num >= max_line_number:
  112.                     break
  113.             # 已经到当前string buff的第一个字符串
  114.             if i == 0:
  115.                 if new_line_pos > 0:
  116.                     line_buffer = string_buffer[0: new_line_pos] + line_buffer
  117.                     out_put_line_list.insert(0, line_buffer)
  118.         # 剩余文件长度大于buffer
  119.         if start_read_pos > buffer_size - 1: # 重新定位开始读取的位置
  120.             start_read_pos = start_read_pos - buffer_size
  121.         # 剩余文件长度小于buffer
  122.         else:
  123.             read_buffer_size = buffer_size - start_read_pos # 减少实际读取的buffer
  124.             start_read_pos = 0 # 读取位置定义到文件头
  125.             if read_line_num < max_line_number:
  126.                 read_line_num = max_line_number - 1
  127.             if file_size < buffer_size:
  128.                 read_line_num = max_line_number
  129.     try:
  130.         f.close()
  131.     except OSError:
  132.         raise ParameterIllegal('close file get os error')
  133.     except IOError:
  134.         raise ParameterIllegal('close file get io error')
  135.     return out_put_line_list



阅读(6602) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~