- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python写一个基于MD5的文件监听程序由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前述 。
写了一个基于md5算法的文件监听程序,通过不同的文件能够生成不同的哈希函数,来实现实现判断文件夹中的文件的增加、修改、删除和过滤含有特定字符的文件名的文件.
需求说明 。
需要实现对一个文件夹下的文件的增加、修改和删除的监控, 一旦发生上述操作,则进行提示。可以选择过滤掉文件名中的特定字符和只监听文件名中含有特定字符的文件.
简述 。
首先,关于文件的增加、修改、删除的反馈,可以想到利用md5等类似的加密算法,因为文件本身可以生成哈希值,只要文件内容或者文件名被修改过,就会生成和修改之前的哈希值不同的值,因此可以利用dict来存储,一个文件名对应一个哈希值来存储。其中增加和删除就对应一个新增加的键值对和一个减少的键值对,而修改则可以理解为删除了旧的文件、增加了一个新的文件.
md5算法可以直接利用第三方的 hashlib 库来实现 。
1
2
3
4
|
m
=
hashlib.md5()
myfile
=
open
(full_path,
'rb'
)
for
line
in
myfile.readlines():
#以行为单位不断更新哈希值,避免文件过大导致一次产生大量开销
m.update(line)
#最后可以得到整个文件的哈希值
|
第二,关于滤掉文件名中的特定字符和只监听文件名中含有特定字符的文件的功能,这个其实非常简单,只需要用 list 分别对需要过滤和必须存在字符串进行存储, 然后利用标志位和字符串的子串包含性进行判断就可以了,只有满足条件的文件可以产生哈希值,产生哈希值也就意味着被监听了.
判断字符串中是否含有字串最常用的方法是 in 和 string 中的 find 方法,这里就不再赘述,可以直接看下面的代码 。
第三,因为要同时监控多个文件夹,所以必须要利用到线程来处理,创建一个线程池来存储线程, 线程利用了 threading 库,并且实现一个线程类来处理线程的操作 。
1
|
class
mylistener(threading.thread):
|
1
|
thread1
=
mylistener(mydir, json_list_include, json_list_exclude)
#生成线程
|
说明 。
需要额外说明的一点是,在传输需要监听的文件夹、必须包含的字段以及过滤字段的时候,我这里是利用配置文件的形式来存储的。说到底,是利用 toml 格式的数据进行的传输,toml格式和 json格式相比,用户的可读性更强一些,为了便于博客展示,因此利用了 toml 格式 。
首先利用代码生成了一下toml格式的文件,以后再想用的话,程序打包之后,可以直接修改配置文件来实现对程序的控制.
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author: jyroooy
import
collections
import
json
import
toml
if
__name__
=
=
'__main__'
:
myorderdict
=
collections.ordereddict
myorderdict
=
{
'dict'
:[{
'path'
:
'e:/testing'
,
'include'
:[
'log_'
],
'exclude'
: [
'.swp'
,
'.swx'
,
'tmp'
]},{
'path'
:
'e:/tmp'
,
'include'
:[
'.record'
],
'exclude'
: [
'.tmp'
]}]}
mytoml
=
toml.dump(myorderdict,
open
(
'e:/python/code/pythonproject/tomlconfig.txt'
,
'w+'
))
|
toml文件 。
格式说明, 一个 dict 对应一个监听的文件夹和需要 过滤(exculde) 和 含有(include) 的字段,解释一下,这里的字段只是文件名的字段,监控 e:/testing 目录下的文件,要包含 log_ 字段的文件,且不包含 .swp .swx .tmp 字段的文件, 并且监控 e:/tmp 目录下的文件,要包含 .record 字段的文件,且不包含 .tmp 的文件.
代码 。
完整程序的代码,具体解释可以看注释 。
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
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author: jyroooy
import
toml
import
hashlib
import
os
import
sys
import
time
import
importlib
import
threading
importlib.
reload
(sys)
class
mylistener(threading.thread):
'''
监听类
'''
def
__init__(
self
, input_dir, filt_in, filt_ex):
#文件夹路径,必须包含的字符,必须过滤的字符
threading.thread.__init__(
self
)
self
.input_dir
=
input_dir
self
.filt_in
=
filt_in
self
.filt_ex
=
filt_ex
self
.
dict
=
{}
#用来存储文件名和对应的哈希值
self
.file_list
=
[]
#存储每一次扫描时的文件的文件名
self
.pop_list
=
[]
#存储需要删除的文件名
def
run(
self
):
while
(
1
):
#保证文件夹一直处于被监听的状态
for
cur_dir, dirs, files
in
os.walk(
self
.input_dir):
if
files !
=
[]:
self
.file_list
=
[]
for
each_file_1
in
files:
each_file
=
each_file_1
if
self
.filt_in:
#判断文件名中是否有必须存在的字段
flagone
=
0
for
i
in
range
(
len
(
self
.filt_in)):
if
self
.filt_in[i]
in
each_file:
flagone
+
=
1
if
flagone
=
=
0
:
continue
if
self
.filt_ex:
#判断文件名中是否有必须过滤掉的字段
flagtwo
=
0
for
i
in
range
(
len
(
self
.filt_ex)):
if
self
.filt_ex[i]
in
each_file:
flagtwo
=
1
if
flagtwo
=
=
1
:
continue
self
.file_list.append(each_file)
full_path
=
os.path.join(cur_dir, each_file)
m
=
hashlib.md5()
#实例化md5算法
myfile
=
open
(full_path,
'rb'
)
for
line
in
myfile.readlines():
m.update(line)
if
each_file
not
in
self
.
dict
.keys():
#如果当前的dict中没有这个文件,那么就添加进去
self
.
dict
[each_file]
=
m.hexdigest()
#生成哈希值
print
(
'文件夹:'
+
cur_dir
+
"中的文件名为:"
+
each_file
+
"的文件为新文件"
+
time.strftime(
'%y-%m-%d %h:%m:%s'
,
time.localtime(time.time())))
if
each_file
in
self
.
dict
.keys()
and
self
.
dict
[each_file] !
=
m.hexdigest():
#如果当前dict中有这个文件,但是哈希值不同,说明文件被修改过,则需要对字典进行更新
print
(
'文件夹:'
+
cur_dir
+
"中的文件名为:"
+
each_file
+
"的文件被修改于"
+
time.strftime(
'%y-%m-%d %h:%m:%s'
,
time.localtime(time.time())))
self
.
dict
[each_file]
=
m.hexdigest()
myfile.close()
pop_list
=
[]
for
i
in
self
.
dict
.keys():
if
i
not
in
self
.file_list:
#当字典中有不在当前文件名列表中时,说明文件已经被删除
print
(
'文件夹:'
+
cur_dir
+
'中的文件名为:'
+
i
+
"的文件已被删除!!!"
+
time.strftime(
'%y-%m-%d %h:%m:%s'
,
time.localtime(time.time())))
pop_list.append(i)
for
i
in
pop_list:
self
.
dict
.pop(i)
time.sleep(
2
)
if
__name__
=
=
'__main__'
:
threads
=
[]
#用来存储线程的线程池
with
open
(
'e:/python/code/pythonproject/tomlconfig.txt'
,
'r+'
) as f:
#读取toml格式的文件,并分解格式
mytoml
=
toml.load(f)
mylist
=
mytoml[
'dict'
]
for
i
in
range
(
len
(mylist)):
#因为可能同时需要监听多个文件夹,所以利用线程池处理多线程
json_list_include
=
[]
json_list_exclude
=
[]
mydir
=
mylist[i][
'path'
]
for
sublist
in
range
(
len
(mylist[i][
'include'
])):
json_list_include.append(mylist[i][
'include'
][sublist])
for
sublist
in
range
(
len
(mylist[i][
'exclude'
])):
json_list_exclude.append(mylist[i][
'exclude'
][sublist])
thread1
=
mylistener(mydir, json_list_include, json_list_exclude)
#生成线程
threads.append(thread1)
for
t
in
threads:
#开启所有线程
t.start();
|
运行结果 。
两个文件夹中的文件 。
第一次运行程序, 可以看到已经按照过滤规则完成了过滤和监听 。
修改 loko.record 文件为 loko.re,再来看结果 。
可以看到已经完成了监听,因为 loko.re 文件,并符合监听的规则,所以不做出监听,而我们前面说过,一个修改相当于一个删除和一个新建操作,所以监听程序提示原文件被删除了 。
写在后面 。
其他的效果我就不一一展示了.
程序也没有实现很复杂的效果,代码已经上传 github -- https://github.com/jyroy/myfilelistener 。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我的支持.
原文链接:https://www.cnblogs.com/jyroy/p/10507653.html 。
最后此篇关于Python写一个基于MD5的文件监听程序的文章就讲到这里了,如果你想了解更多关于Python写一个基于MD5的文件监听程序的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要(我必须)将大量 float 写入 qdatastream 并且我只使用 4 个字节是必要的。setFloatingPointPrecision 或为 float 和 double 写入 4 或
我有一些 C 代码,我用 Python 对其进行了扩展。扩展的 C 代码有一个将一些结构附加到二进制文件的函数: void writefunction(const struct struct1* so
我正在用 C 语言开发一个小软件,用于在布告栏中读取和写入消息。每条消息都是一个以渐进数字命名的 .txt。 软件是多线程的,有很多用户可以并发操作。 用户可以进行的操作有: 阅读整个公告板(所有 .
我有 2 个线程同时访问同一个大文件 (.txt)。 第一个线程正在从文件中读取。第二个线程正在写入文件。 两个线程都访问同一个 block ,例如(开始:0, block 大小:10),但具有不同的
我做了很多谷歌搜索,但我仍然不确定如何继续。 Linux 下最常见的剪贴板读写方式是什么?我想要同时支持 Gnome 和 KDE 桌面。 更新:我是否认为没有简单的解决方案,必须将多个来源(gnome
1. 定义配置文件信息 有时候我们为了统一管理会把一些变量放到 yml 配置文件中 例如 图片 用 @ConfigurationProperties 代替 @Value 使用方法 定义对应字段的实体
在开始之前,我必须先声明我是 FORTRAN 的新手。我正在维护 1978 年的一段遗留代码。它的目的是从文件中读取一些数据值,处理这些值,然后将处理过的值输出到另一个文本文件。 给定以下 FORTR
我正在制作一个应用程序,我需要存储用户提供的一些信息。我尝试使用 .plist 文件来存储信息,我发现: NSString *filePath = @"/Users/Denis/Documents/X
在delphi类中声明属性时是否可能有不同类型的结果? 示例: 属性月份:字符串读取monthGet(字符串)写入monthSet(整数); 在示例中,我希望在属性(property)月份中,当我:读
我正在以二进制形式将文件加载到数组中,这似乎需要一段时间有没有更好更快更有效的方法来做到这一点。我正在使用类似的方法写回文件。 procedure openfile(fname:string); va
我想实现一个运行模拟的C#控制台应用程序。另外,我想给用户机会在控制台上按“+”或“-”来加速/减速模拟的速度。 有没有办法在编写控制台时读取控制台?我相信我可以为此使用多线程,但是我却不怎么做(我对
这是我的代码: use std::fs::File; use std::io::Write; fn main() { let f = File::create("").unwrap();
我有一个应用程序可以访问 csv 文本文件中的单词。由于它们通常不会更改,因此我将它们放置在 .jar 文件中,并使用 .getResourceAsStream 调用读取它们。我真的很喜欢这种方法,因
我使用kubeadm,docker 17.12.1-ce和法兰绒网络安装了Kubernetes 1.13.1集群 但是,我发现Kubernetes主服务器上有许多空文件,权限为666,该文件允许任何用
我的工作区中有一些 java 文件。现在我想编写一个java程序,它可以读取来自不同源的文本文件,一次一个,一行一行,并将这些行插入到工作区中各自的java文件中。 文本文件会告诉我将哪个文件插入到哪
用户A要求系统读取文件foo,同时用户B想要将他或她的数据保存到同一个文件中。在文件系统级别如何处理这种情况? 最佳答案 大多数文件系统(但不是全部)使用锁定来保护对同一文件的并发访问。锁可以是独占的
我对保护移动应用程序的 firebase 数据库有一些疑问。 例如,在反编译Android应用程序后,黑客可以获取firebase api key 然后访问firebase数据库,这是正确的吗? 假设
我想让文件从外部不可删除,并希望使用java从程序对该文件进行读/写操作。 S0,我使用以下代码使用java创建了不可删除的文件: Process pcs = Runtime.getRunti
当 Selector.select() 以阻塞模式等待读/写操作时,是否可以将写消息推送到客户端?如何将选择器从阻塞模式移至写入模式?触发器可以是一个后台线程,用于放置需要写入给定 channel 的
我目前正在学习在 Linux 环境中使用 C 进行套接字编程。作为一个项目,我正在尝试编写一个基本的聊天服务器和客户端。 目的是让服务器为每个连接的客户端派生一个进程。 我遇到的问题是读取一个 chi
我是一名优秀的程序员,十分优秀!