文章目录

  • 一、前言
  • 二、读取fllow源码
    • 1、fllow读取文件代码
    • 2、跟踪new_file_check 函数
    • 3、python的stat函数
    • 4、分析出错代码
  • 三、windows下对比inode 节点号
    • 1、windows下打印这几个参数
    • 2、os.start() 与 os.fstat()
    • 3、linux文件的inode会保持不变吗?
    • 4、windows文件的inode会保持不变吗?
  • 四、解决方案
  • 五、总结

一、前言

python通过fllow读取文件,需求是可以监控log文件,当文件行数增加的话,就写入到数据库,也可以读取历史log文件,写入到数据库,因此我们通过给脚本添加参数的方式来区分是否监控log文件。

可是当执行python的时候,明明log文件没有新增数据,但是发现每隔60spython就会读取log文件的旧数据,并插入到数据库。这当然是不符合需求的,正常来说,log文件无变化,fllow不应该再去读取文件才对。

二、读取fllow源码

遇到文件就读源码,码中自有黄金屋,码中自有颜如玉。

1、fllow读取文件代码

thefile = follow.Follow(filename, False)fllow的Follow函数如下:
class Follow(object):def __init__(self, fname, start=False, new_file_check=60, *open_args):

可以看到参数中有个new_file_check =60,这个参数会不会就是罪魁祸首呢?

2、跟踪new_file_check 函数

def _preread(self):if not self.f:self._reopen(False)returnt = time.time()if t >= self.stat_time + self.stat_time_min:   # 这部分用到了nstat = os.stat(self.fname)self.stat_time = tif nstat.st_dev != self.stat.st_dev or \nstat.st_ino != self.stat.st_ino:# start at top of new fileself._reopen(True)return# should clear previous EOF conditionself.f.seek(self.pos)

代码的语意是:

60s之后,脚本会重新获取文件的相关属性,并对比文件的相关参数,若参数不一致则重新读取文件。

看来问题就出在了这个对比属性上,下面先看看这些属性都是什么意思

3、python的stat函数

根据if条件左边的代码格式,我们知道是用os.stat()函数的返回值进行对比的。
根据if条件右边的代码格式,我们可追踪代码,最终锁定在os.fstat()函数

手册解析:

https://www.runoob.com/python/os-stat.html
os.stat() 方法用于在给定的路径上执行一个系统 stat 的调用。

https://www.runoob.com/python/os-fstat.html
os.fstat() 方法用于返回文件描述符fd的状态,类似 stat()Unix,Windows上可用。

根据这个教程,我们发现

os.stat返回的结果有:

st_mode: inode 保护模式
st_ino: inode 节点号。
st_dev: inode 驻留的设备。
st_nlink: inode 的链接数。 等

os.fstat返回的结果有:

st_dev: 设备信息
st_ino: 文件的i-node值

4、分析出错代码

if nstat.st_dev != self.stat.st_dev or \nstat.st_ino != self.stat.st_ino:# start at top of new fileself._reopen(True)return
首先是对比: inode 驻留的设备 != 设备信息
其次是对比:inode 节点号 != 文件的i-node值

两次对比有一次不同则重新读取文件,也就是造成我们上面的bug

三、windows下对比inode 节点号

1、windows下打印这几个参数

   print nstat.st_devprint self.stat.st_devprint nstat.st_inoprint self.stat.st_ino结果:
0
0
0
73746443898579758

OK,根据结果已经知道是文件的inode值不同,所以造成了重新读取文件的bug。那么为什么文件属性会发生变化呢,本地数据量又没有增加。而且既然这个文件是常用的读取文件脚本,那么怎么可能会有这明显的bug

2、os.start() 与 os.fstat()

首先明确一点,两个函数都能在windows下正常运行。函数含义也有些相似,唯一不一样的一点就是inode的值,关于inode,听说最多的就是linux文件系统的inode了,那么会不会是windows下的inodelinuxinode不一样,或者windows不够稳定呢

3、linux文件的inode会保持不变吗?

答案:
      inode在文件的生命周期里是不改变的,除非,你把文件删除重建。而你删除文件前100行的动作,实际上是新建一个临时文件,把旧文件第100行以后的东西输出到临时文件里,删掉旧文件,把临时文件的文件名重命名成旧文件的名字。也就是说你删前100行的时候,文件已经经历了删除-重建的过程,inode号也就改变了。

作者:北极
链接:https://www.zhihu.com/question/26127845/answer/32214159
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4、windows文件的inode会保持不变吗?

通过搜索我们发现,对于windows来说,它有类似于inode的概念,比如通过卷序列号/ FileId组合等来标识目录文件,但是windows下并没有直接的inode概念,所以在windows下通过inode对比文件是不稳定且不精准的。

关于windows的inode,有兴趣的可以参考:
http://zgserver.com/windowsinode.html
http://cn.voidcc.com/question/p-nvmqdzhb-vo.html

这样一对比,答案就很明显了,windows下问题奇葩问题多,怪不得大佬们都用mac电脑开发呢,大佬们果然诚不我欺。

四、解决方案

通过以上的分析,可以知道这个锅算是windows的锅,怪不得py脚本在windows下那么多的bug,因为windowslinux在某些函数调用上还是有一些差距的,建议是到linux服务器上跑一跑看看。

因此上传py脚本到linux,在linux上测试,发现完美实现监控日志文件的目的,文件有更新则写入到数据库,无更新则持续读取。

五、总结

通过这篇文章的分析,对博主对打的触动就是:windows环境果然是坑。 怪不得大佬们都是用mac电脑,天天在linux下开发呢,博主本来在windows下开发php开发的不亦乐乎,只可惜以后始终是要用到编译型语言的,早晚都要完全在linux下开发啊。。

行吧,解决问题的过程永远是复杂的,查找的过程永远是享受,通过这个问题博主又学到了很多python的知识,整体来说还是很赞的。

我是铁柱,我为自己代言!

end

windows下python使用fllow扩展持续读取文件的bug相关推荐

  1. windows下sublime通过sftp扩展上传文件到linux服务器上

    首先在package controll下载sftp扩展,在任意磁盘下新建文件夹: 然后,添加该文件夹到sublime中,并在xhell中链接linux服务器,新建目录,mkdir  /home/hel ...

  2. windows下python读取网络摄像头

    windows下python读取网络摄像头 这几天天天搭建环境,都快疯了,到处找包,到处安装,到处出错,读不出来网络摄像头,不过经过不懈努力终于把环境配好了,真不容易,在上一篇VSCode+pytho ...

  3. 简述Linux和Windows下Python搭建步骤

    简述就Windows和Linux环境下安装Python的步骤. Python环境搭建首先到官网(www.python.org)下载相应的安装版本.主要分为Windows和Linux两种: 一.Linu ...

  4. Windows下Python 3.6 + VS2017 + Anaconda 解决Unable to find vcvarsall.bat问题

    Windows下Python 3.6 + VS2017 + Anaconda 解决Unable to find vcvarsall.bat问题 参考文章: (1)Windows下Python 3.6 ...

  5. php7 mcrypt windows,Windows下php安装mcrypt扩展问题

    首先我们看看报错问题:Call to undefined function App\Http\PayModels\Online\mcrypt_get_block_size(),然后我就不断的去找度娘, ...

  6. windows下php7安装redis扩展

    windows下php7安装redis扩展 windows下开发用的wamp集成的环境,想装个php-redis扩展. php_redis.dll下载地址:https://pecl.php.net/p ...

  7. windows下python环境搭建_Linux/Windows下Python环境搭建步骤

    Python环境搭建首先到官网(www.python.org)下载相应的安装版本.主要分为Windows和Linux两种: 一.Linux下Python环境搭建 一般情况下,Linux系统都已经预安装 ...

  8. Windows 下python的tab自动补全

    Windows 下python的tab自动补全 对于新学python的朋友来说,python模块的功能多而难记,mac和Linux中有tab自动补全命令功能,使用Windows的同学们怎么办?下面我们 ...

  9. python2没有pip命令_解决Windows下python和pip命令无法使用的问题

    一. python命令找不到 安装python之后经常会出现下面的问题 , python命令找不到,这是因为Windows的环境变量中没有定义python的安装路径 这个时候我们先找到python的安 ...

最新文章

  1. C++语言程序设计之关联容器类型
  2. Ehcache BigMemory: 摆脱GC困扰(转)
  3. [Java基础]字节,字符打印流
  4. python杀死了excel_Python杀死了Excel|自动更新表格,告别繁琐
  5. boot druid 长时间不连接 异常_Spring Boot学习:如何使用Druid数据源
  6. hbase1.1.1 连接集群_Hadoop2.7.1+Hbase1.1.2集群环境搭建(10) hadoop hbase kerberos
  7. WIN7 系统破解LoadRunner 11
  8. gitlab 的使用策略和简单介绍
  9. jsTree使用记录
  10. python数据挖掘学习笔记】十六.逻辑回归LogisticRegression分析鸢尾花数据
  11. Pytorch——保存训练好的模型参数
  12. 简述负载均衡CDN技术
  13. 第一章-网络安全行业
  14. 解决:启动springboot项目,Unable to start web server; nested exception is org.springframework.beans.factory
  15. 为什么没写Feedsky话题广告
  16. 计算机tpm管理,【教程】安装 Windows 11 的三种方法,绕过TPM2.0
  17. “因遭勒索软件攻击,我被认定工作失职开除,并被老东家索赔 21.5 万元”
  18. candence pcb走线等长_PCB走线角度选择 - PCB Layout 跳坑指南 - 吴川斌的博客
  19. 施工控制网的精度确定方法?
  20. [代码解读]基于多代理RL的车联网频谱分享_Python实现

热门文章

  1. 天籁obd接口针脚定义_OBD协议介绍
  2. SimBERTv2 融合检索和生成的RoFormer-Sim模型
  3. CircleLoss
  4. module 'tensorflow' has no attribute 'Session'
  5. C2893 未能使函数模板“unknown-type std::invoke(_Callable ,_Types ...)”专用化 websocket_server
  6. python sharedctypes 多进程性能测试
  7. windows msys编译64位x264和ffmpeg
  8. python 排列组合之itertools
  9. Minimal BASH-like line editing
  10. mysql四列数据表代码_MySQL数据库常用代码