文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

面试宝典_Python.运维开发.000

2023-01-31 06:57

关注

面试题目:

1. 用PYTHON实现tail -f功能,默认显示最后15行,实时输出新增行?


解题思路:

1. 此需求在很多场景中都有遇到,而且在各大群中也被讨论过,虽然有现成的模版如pyinotify等模块实现,但面试更想通过你的解题思路来判断这场面试,具体到tail需要实现2个功能,一个实时输出新增内容,一个默认输出前15行,前者直接循环打开文件读取,全局变量中记录上次读取的位置,下一次循环seek到上次的位置读取即可,而对于默认显示前15行的做法是假设一行1000个字节,循环读取,当文件总长度小于1000时则从开头开始读取分割行取出后10行即可,即使不够10行也没关系,当文件总长度大于等于1000时,如果分割后大于10行,则读取分割行取出后10行即可,如果小于10行则继续向前1000个读取,以此类推~


具体实现:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# 51CTOBG: http://xmdevops.blog.51cto.com/
# Purpose:
#
"""
from __future__ import absolute_import
# 说明: 导入公共模块
import os 
import sys
import time
import chardet
# 说明: 导入其它模块
# 


if __name__ == '__main__':
    seekps = 0;
    target = 'data.txt';

    try:
        # 指针跳到最后作为起读位置
        with open(target, 'r+b') as f:
            f.seek(0, os.SEEK_END)
            seekps = f.tell()
            print 'notice: file length is', seekps
            rest_lines = []
            # 默认读取15行
            line_reads = 15
            # 假设默认每行1000字节
            line_bytes = 1000
            '''
            1. 当f_length < line_bytes,就seek到0开始读取,读完break
            2. 当f_length > line_bytes,换行符数n表示n+1行
               => 当n+1 >= line_reads,取出其中前line_reads个元素
               => 当n+1 <  line_reads,继续向前seek到count*line_reads位置读取
            '''
            count = 1
            while True:
                if seekps <= line_bytes*count:
                    f.seek(0)
                    rest_lines = f.read().split(os.linesep)[-line_reads:]
                    break
                f.seek(-1*line_bytes*count, 2)
                rest_lines = f.read().split(os.linesep)
                if len(rest_lines)>=line_reads:
                    rest_lines = rest_lines[-line_reads:]
                    break
                else:
                    count += 1

            for line in rest_lines:
                code = chardet.detect(line).get('encoding')
                line = line.decode(code).encode(sys.stdout.encoding)
                sys.stdout.write(''.join([line.strip(), os.linesep]))
                sys.stdout.flush()

    except Exception, e:
        print 'notice: open file with error({0})'.format(e)
        exit()

    print 'notice: start position is', seekps
    while True:
        try:
            with open(target, 'r+b') as f:
                f.seek(0, os.SEEK_END)
                # 防止数据被意外截断
                if f.tell()<seekps:
                    f.seek(f.tell())
                else:
                    f.seek(seekps)

                while True:
                    line = f.readline()
                    if not line.strip():
                        break
                    code = chardet.detect(line).get('encoding')
                    line = line.decode(code).encode(sys.stdout.encoding)
                    sys.stdout.write(''.join([line.strip(), os.linesep]))
                    sys.stdout.flush()
                seekps = f.tell()
        except Exception, e:
            print 'notice: open file with error({0})'.format(e)
            break
        time.sleep(0.1)


有图有像:

wKioL1iXNFngMPcWAABFkWpclw8083.png

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯