windows下python使用fllow扩展持续读取文件的bug
文章目录
- 一、前言
- 二、读取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
文件没有新增数据,但是发现每隔60s
,python
就会读取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
下的inode
和linux
的inode
不一样,或者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
,因为windows
和linux
在某些函数调用上还是有一些差距的,建议是到linux
服务器上跑一跑看看。
因此上传py
脚本到linux
,在linux
上测试,发现完美实现监控日志文件的目的,文件有更新则写入到数据库,无更新则持续读取。
五、总结
通过这篇文章的分析,对博主对打的触动就是:windows环境果然是坑。 怪不得大佬们都是用mac
电脑,天天在linux
下开发呢,博主本来在windows
下开发php
开发的不亦乐乎,只可惜以后始终是要用到编译型语言的,早晚都要完全在linux
下开发啊。。
行吧,解决问题的过程永远是复杂的,查找的过程永远是享受,通过这个问题博主又学到了很多python
的知识,整体来说还是很赞的。
我是铁柱,我为自己代言!
end
windows下python使用fllow扩展持续读取文件的bug相关推荐
- windows下sublime通过sftp扩展上传文件到linux服务器上
首先在package controll下载sftp扩展,在任意磁盘下新建文件夹: 然后,添加该文件夹到sublime中,并在xhell中链接linux服务器,新建目录,mkdir /home/hel ...
- windows下python读取网络摄像头
windows下python读取网络摄像头 这几天天天搭建环境,都快疯了,到处找包,到处安装,到处出错,读不出来网络摄像头,不过经过不懈努力终于把环境配好了,真不容易,在上一篇VSCode+pytho ...
- 简述Linux和Windows下Python搭建步骤
简述就Windows和Linux环境下安装Python的步骤. Python环境搭建首先到官网(www.python.org)下载相应的安装版本.主要分为Windows和Linux两种: 一.Linu ...
- 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 ...
- php7 mcrypt windows,Windows下php安装mcrypt扩展问题
首先我们看看报错问题:Call to undefined function App\Http\PayModels\Online\mcrypt_get_block_size(),然后我就不断的去找度娘, ...
- windows下php7安装redis扩展
windows下php7安装redis扩展 windows下开发用的wamp集成的环境,想装个php-redis扩展. php_redis.dll下载地址:https://pecl.php.net/p ...
- windows下python环境搭建_Linux/Windows下Python环境搭建步骤
Python环境搭建首先到官网(www.python.org)下载相应的安装版本.主要分为Windows和Linux两种: 一.Linux下Python环境搭建 一般情况下,Linux系统都已经预安装 ...
- Windows 下python的tab自动补全
Windows 下python的tab自动补全 对于新学python的朋友来说,python模块的功能多而难记,mac和Linux中有tab自动补全命令功能,使用Windows的同学们怎么办?下面我们 ...
- python2没有pip命令_解决Windows下python和pip命令无法使用的问题
一. python命令找不到 安装python之后经常会出现下面的问题 , python命令找不到,这是因为Windows的环境变量中没有定义python的安装路径 这个时候我们先找到python的安 ...
最新文章
- C++语言程序设计之关联容器类型
- Ehcache BigMemory: 摆脱GC困扰(转)
- [Java基础]字节,字符打印流
- python杀死了excel_Python杀死了Excel|自动更新表格,告别繁琐
- boot druid 长时间不连接 异常_Spring Boot学习:如何使用Druid数据源
- hbase1.1.1 连接集群_Hadoop2.7.1+Hbase1.1.2集群环境搭建(10) hadoop hbase kerberos
- WIN7 系统破解LoadRunner 11
- gitlab 的使用策略和简单介绍
- jsTree使用记录
- python数据挖掘学习笔记】十六.逻辑回归LogisticRegression分析鸢尾花数据
- Pytorch——保存训练好的模型参数
- 简述负载均衡CDN技术
- 第一章-网络安全行业
- 解决:启动springboot项目,Unable to start web server; nested exception is org.springframework.beans.factory
- 为什么没写Feedsky话题广告
- 计算机tpm管理,【教程】安装 Windows 11 的三种方法,绕过TPM2.0
- “因遭勒索软件攻击,我被认定工作失职开除,并被老东家索赔 21.5 万元”
- candence pcb走线等长_PCB走线角度选择 - PCB Layout 跳坑指南 - 吴川斌的博客
- 施工控制网的精度确定方法?
- [代码解读]基于多代理RL的车联网频谱分享_Python实现
热门文章
- 天籁obd接口针脚定义_OBD协议介绍
- SimBERTv2 融合检索和生成的RoFormer-Sim模型
- CircleLoss
- module 'tensorflow' has no attribute 'Session'
- C2893 未能使函数模板“unknown-type std::invoke(_Callable ,_Types ...)”专用化 websocket_server
- python sharedctypes 多进程性能测试
- windows msys编译64位x264和ffmpeg
- python 排列组合之itertools
- Minimal BASH-like line editing
- mysql四列数据表代码_MySQL数据库常用代码