Python Watchdog:高效的文件系统监控
1. 写在前面
在软件开发中,有时候需要通过 Python 去监听指定区域文件或目录的创建、修改,或者删除,从而引发特定的事件处理。本篇博客为你介绍第三方模块 Watchdog 实现对文件事件的监控。
公众号: 滑翔的纸飞机
2. Watchdog
2.1 什么是 Watchdog?
用于监视文件系统事件的 Python API 和 shell 实用程序。
**项目地址:**https://pypi.org/project/watchdog/
**最新版本:**Watchdog 3.0.0 适用于 Python 3.7+
**安装:**需要运行以下命令进行安装(确保使用的是 Python 3.7+):
pip install watchdog
2.2 官方快速入门示例
以下示例程序:将以递归方式监视当前目录文件系统变更,并简单地将它们输出到控制台;
import sys
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandlerif __name__ == "__main__":# 设置日志信息格式logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')# 要监控的目录路径path = sys.argv[1] if len(sys.argv) > 1 else '.'# 创建一个日志事件处理程序event_handler = LoggingEventHandler()# 创建一个观察者对象observer = Observer()# 声明一个定时任务observer.schedule(event_handler, path, recursive=True)# 启动定时任务observer.start()try:while observer.is_alive():observer.join(1)finally:observer.stop()observer.join()
输出: 跟踪目录变更事件,通过日志输出变更记录。
例如: 创建 test > 1.txt 控制台输出:
2023-10-19 00:56:18 - Created directory: /Users/demo/2023/10/watchdog/test
2023-10-19 00:56:18 - Modified directory: /Users/demo/2023/10/watchdog
2023-10-19 00:56:27 - Created file: /Users/demo/2023/10/watchdog/test/1.txt
2023-10-19 00:56:27 - Modified directory: /Users/demo/2023/10/watchdog/test
2.3 Event Handler 和 Observer
Watchdog 的主要实现或者可以说 Watchdog 的构件是基于以下类:
- Observer:观察者,用于监视目录并将调用分派给事件处理程序;
- Event handler: 文件系统事件和事件处理程序;
说白了,Observer 监控目录,触发 Event handler 针对事件做出响应;
导入方式:
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
2.3.1 Event handler
以下是Watchdog中默认提供的4个事件处理类:
- FileSystemEventHandler:文件,事件处理器的基类,用于处理事件;
- PatternMatchingEventHandler:模式匹配文件;
- RegexMatchingEventHandler:正则匹配文件;
- LoggingEventHandler:记录日志。
有关处理程序的更多详情,请参阅此链接
通过扩展 Watchdog 提供的默认事件处理程序类,实现自定义的函数来处理修改、创建、删除和移动事件。还可以覆盖 FileSystemEventHandler 中的函数(以下函数),因为其他事件处理类都继承自该类。
**on_any_event(event):**捕获所有事件处理程序;
**on_created(event):**在创建文件或目录时调用;
**on_deleted(event):**删除文件或目录时调用;
**on_modified(event):**当文件或目录被修改时调用;
**on_moved(event):**在移动或重命名文件或目录时调用;
**on_closed(event):**文件已关闭时调用;
**on_opened(event):**打开文件时调用;
每个函数都有一个名为 event 的输入参数,其中包含以下变量:
- event_type:字符串形式的事件类型(“moved”、“deleted”、“created”、“modified”、“closed”、“opened”),默认为 “无”;
- is_directory:True:表示事件针对目录;
- src_path:触发此事件的文件系统对象的源路径;
2.3.2 Observer
如果大家熟悉设计模式,那么 Watchdog 就遵循观察设计模式。因此,每个观察者都会有事件,如果文件或目录有任何变化,它就会查看并显示变化。
Observer,观察目录,针对事件调用处理程序,也可以直接导入特定平台的类,并用它代替 Observer
2.3.3 回顾上文简单示例
通过上述介绍,对 Event handler 和 Observer有一个简单的理解,现在我们回过头继续来看官方示例:
import sys
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandlerif __name__ == "__main__":# 设置日志信息格式logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')# 要监控的目录路径path = sys.argv[1] if len(sys.argv) > 1 else '.'# 创建一个日志事件处理程序event_handler = LoggingEventHandler()# 创建一个观察者对象observer = Observer()# 声明一个定时任务observer.schedule(event_handler, path, recursive=True)# 启动定时任务observer.start()try:while observer.is_alive():observer.join(1)finally:observer.stop()observer.join()
(1)event_handler = LoggingEventHandler(): 创建一个日志事件处理程序;
(2)observer = Observer():创建一个观察者对象;
(3)observer.schedule(event_handler, path, recursive=True):声明一个定时任务,传入事件处理程序、监控路径、以及是否递归子目录;
(4)observer.start():启动定时任务;
进一步分析下:
schedule(self, event_handler, path, recursive=False):
该方法用于监视 path 路径,并调用给定的事情 event_handler 。
参数 recursive 表示是否递归子目录,即监听子目录,默认为 False。
start():
启动线程,这里开启了新的守护线程,主程序如果结束, 该线程也会停止。
每个线程对象只能调用1次,它安排对象的 run() 方法在单独的控制线程中调用,如果在同一线程对象上多次调用此方法将引发 RuntimeError。
2.4. 理解和使用
基于上述关键概念介绍以及官方示例,自己实现一个文件事件监听;
在本例中,使用 FileSystemEventHandler 事件类。对一个文件夹设置监视,并在有文件产生时触发另一个函数。处理完成后,将把文件移到另一个文件夹。
(1)首先,你需要创建一个继承自 FileSystemEventHandler 事件处理类,并创建一个观察者和自定义的事件处理程序实例。
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandlerclass MyHandler(FileSystemEventHandler):passobserver = Observer()
event_handler = MyHandler()
(2)创建一个定时任务,传入以下参数
- event_handler:刚创建的处理程序对象;
- path:要跟踪的文件夹路径;
- recursive:是否递归子目录;
observer.schedule(event_handler, path='./input_files', recursive=True)
(3) observer.start() - 启动任务,等待目录产生事件,触发事件处理程序中的代码。
(4) observer.stop() - 该函数将清理资源。
(5) 最后用 observer.join() 结束,因为我们在这里使用的是多线程概念。join() 将连接多个线程,直到调用 join 方法的线程终止。
observer.start()
try:while True:time.sleep(300)
except KeyboardInterrupt:observer.stop()
observer.join()
接下去,自定义事件处理类:MyHandler
在这个示例中,我将检查是否有文件上传到所跟踪的文件夹中。为此,我可以使用 on_created(event):
def create_directory(file_path=None):# 以'年-月-日'的格式获取当前日期current_date = datetime.now().strftime('%Y-%m-%d')# 创建一个包含当前日期的文件夹folder_path = f'{file_path}/{current_date}'if not os.path.exists(folder_path):os.makedirs(folder_path)return folder_pathelse:return folder_pathclass MyHandler(FileSystemEventHandler):def on_created(self, event):dir_path = event.src_path.split('/input_files')processed_files = f'{dir_path[0]}/processed_files'child_processed_dir = create_directory(file_path=processed_files)if event:print("file created:{}".format(event.src_path))# 这里调用其他处理函数main(file_name=event.src_path)file_name = event.src_path.split('/')[-1]destination_path = f'{child_processed_dir}/{file_name}'# 将文件移动到其他目录shutil.move(event.src_path, destination_path)print("file moved:{} to {}".format(event.src_path, destination_path))
在上面的示例中,我使用函数 create_directory() 来检查目标路径中是否有当前日期的文件夹,否则就创建相同的文件夹。
然后,在其他 python 脚本函数 main() 中做了一些处理后,使用相同的路径作为目标路径来移动文件
下面是最终代码:my_event_handler.py
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import shutil
import time
import os
from datetime import datetime
from watchdog_fileobserver import maindef create_directory(file_path=None):# 以'年-月-日'的格式获取当前日期current_date = datetime.now().strftime('%Y-%m-%d')# 创建一个包含当前日期的文件夹folder_path = f'{file_path}/{current_date}'if not os.path.exists(folder_path):os.makedirs(folder_path)return folder_pathelse:return folder_pathclass MyHandler(FileSystemEventHandler):def on_created(self, event):dir_path = event.src_path.split('/input_files')processed_files = f'{dir_path[0]}/processed_files'child_processed_dir = create_directory(file_path=processed_files)if event:print("file created:{}".format(event.src_path))# 这里调用其他处理函数main(file_name=event.src_path)file_name = event.src_path.split('/')[-1]destination_path = f'{child_processed_dir}/{file_name}'shutil.move(event.src_path, destination_path)print("file moved:{} to {}".format(event.src_path, destination_path))if __name__ == "__main__":observer = Observer()event_handler = MyHandler()observer.schedule(event_handler, path='./input_files', recursive=True)observer.start()try:while True:time.sleep(300)except KeyboardInterrupt:observer.stop()observer.join()
watchdog_fileobserver.py:
import csvdef read_csv_file(file_name):try:with open(f"{file_name}", 'r') as file:csvreader = csv.DictReader(file)for row in csvreader:print(row)return csvreaderexcept Exception as e:passdef main(file_name=None):if file_name:dict_data = read_csv_file(file_name)print("Process completed")else:print("Invalid file path")
在这种情况下,需要等待文件上传,然后执行所需的操作。为此,你可以在事件函数中添加以下代码:
def on_created(self, event):file_size = -1while file_size != os.path.getsize(event.src_path):file_size = os.path.getsize(event.src_path)print(file_size)time.sleep(1)### OR ###def on_created(self, event):file = Nonewhile file is None:try:file = open(event.src_path)except OSError:logger.info('Waiting for file transfer....')time.sleep(1)continue
验证:
脚本所在路径下,创建用于监听目录 input_files, 在该目录下创建一个文件,控制台输出:
file created:/Users/demo/2023/10/watchdog/input_files/text.txt
Process completed
file moved:/Users/demo/2023/10/watchdog/input_files/text.txt to /Users/demo/2023/10/watchdog/processed_files/2023-10-20/text.txt
目录如下:
.
├── input_files
├── my_event_handler.py
├── processed_files
│ └── 2023-10-20
│ └── text.txt
└── watchdog_fileobserver.py
2.5. Watchdog 使用案例
2.5.1 忽略子目录或只包含模式匹配文件的情况
如果要忽略某个目录中的某些文件,可以使用最简单的方法之一,即使用 PatternMatchingEventHandler
在文件 my_event_handler.py 中,修改 MyHandler 中的继承类(PatternMatchingEventHandler),如下所示:
class MyHandler(PatternMatchingEventHandler):........if __name__ == "__main__":event_handler = MyHandler(patterns=["*.csv", "*.pdf"],ignore_patterns=[],ignore_directories=True)........
2.5.2 使用 Celery 来启动/停止 Watchdog
可以使用下面的示例来实现 Watchdog。不过,这个示例只是一个关于如何将 celery 集成到Watchdog 中的想法。
from celery import Celery
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
import os
import timeapp = Celery('celery_ex.celery_apptask_ex', broker='redis://localhost:6379/0')@app.task
def process_file(file_path):# do something with the filewith open(file_path, 'r') as f:print(f.read())class MyHandler(PatternMatchingEventHandler):def on_created(self, event):file_size = -1while file_size != os.path.getsize(event.src_path):file_size = os.path.getsize(event.src_path)print(file_size)time.sleep(1)if event:print("file created:{}".format(event.src_path))# call function hereprocess_file.apply_async(args=(event.src_path,))if __name__ == "__main__":observer = Observer()event_handler = MyHandler(patterns=["*.csv", "*.pdf"],ignore_patterns=[],ignore_directories=True)observer.schedule(event_handler, path='./input_files', recursive=True)observer.start()try:while True:time.sleep(1)except KeyboardInterrupt:observer.stop()observer.join()
此示例需要 redis、celery 支持;
2.5.3 监控目录变化
观察者(observer)可以设置指定目录及其所有子目录,在文件或目录创建、删除或修改时调用相应的方法(on_created、on_deleted 或 on_modified),观察者以无限循环的方式运行,可以被键盘中断打断。
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandlerclass EventHandler(FileSystemEventHandler):def on_created(self, event):if event.is_directory:print("Directory created:", event.src_path)else:print("File created:", event.src_path)def on_deleted(self, event):if event.is_directory:print("Directory deleted:", event.src_path)else:print("File deleted:", event.src_path)def on_modified(self, event):if event.is_directory:print("Directory modified:", event.src_path)else:print("File modified:", event.src_path)event_handler = EventHandler()
observer = Observer()
observer.schedule(event_handler, "/path/to/dir", recursive=True)
observer.start()try:while True:time.sleep(1)
except KeyboardInterrupt:observer.stop()
observer.join()
2.5.4 使用线程和多进程执行 Watchdog 来启动独立进程
可以运行 Watchdog,使用线程和多进程并行处理多个文件。下面是一个相同的示例:
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
import os
import ntpath
import time
import optparse
import multiprocessing
import threading
from collections import OrderedDictlock = threading.RLock()def process_function(get_event, event_dict):print(f"Process started for event: {get_event}")dir_path = ntpath.abspath(get_event)file_name = ntpath.basename(get_event)if len(get_event) > 0:your_own_function()do something....class Handler(PatternMatchingEventHandler):def __init__(self, queue):PatternMatchingEventHandler.__init__(self, patterns=['*.csv'],ignore_patterns=[],ignore_directories=True)self.queue = queuedef on_created(self, event):# logger.info(f"Wait while the transfer of the file is finished before processing it")# file_size = -1# while file_size != os.path.getsize(event.src_path):# file_size = os.path. getsize(event.src_path)# time.sleep(1)file = Nonewhile file is None:try:file = open(event.src_path)except OSError:logger.info('Waiting for file transfer')time.sleep(5)continueself.queue.put(event.src_path)def on_modified(self, event):passdef start_watchdog(watchdog_queue, dir_path):logger.info(f"Starting Watchdog Observer\n")event_handler = Handler(watchdog_queue)observer = Observer()observer.schedule(event_handler, dir_path, recursive=False)observer.start()try:while True:time.sleep(1)except Exception as error:observer.stop()logger.error(f"Error: {str(error)}")observer.join()if __name__ == '__main__':dir_path = r'//file_path/'watchdog_queue = Queue()logger.info(f"Starting Worker Thread")worker = threading.Thread(target=start_watchdog, name="Watchdog",args=(watchdog_queue, dir_path), daemon=True)worker.start()mp = Manager()event_dict = mp.dict()while True:if not watchdog_queue.empty():logger.info(f"Is Queue empty: {watchdog_queue.empty()}")pool = Pool()pool.apply_async(process_function, (watchdog_queue.get(), event_dict))else:time.sleep(1)
2.5.5 在 Watchdog 中进行日志记录
要记录事件,可以创建一个继承自 FileSystemEventHandler 类的自定义事件处理程序类,并重写与要记录的事件相对应的方法。
下面举例说明如何使用 Watchdog 库记录文件创建和修改事件:
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandlerclass LogEventHandler(FileSystemEventHandler):def on_created(self, event):if not event.is_directory:logging.info(f"File created: {event.src_path}")def on_modified(self, event):if not event.is_directory:logging.info(f"File modified: {event.src_path}")logging.basicConfig(filename='watchdog.log', level=logging.INFO, format='%(asctime)s - %(message)s')
event_handler = LogEventHandler()
observer = Observer()
observer.schedule(event_handler, "/path/to/", recursive=True)
observer.start()try:while True:time.sleep(1)
except KeyboardInterrupt:observer.stop()
observer.join()
3. 最后
无论你是在一个需要跟踪多个文件的大型项目中工作,还是只想关注单个文件的任务,Watchdog 库都能满足你的需求。
感谢您花时间阅读文章
关注公众号不迷路
相关文章:

Python Watchdog:高效的文件系统监控
1. 写在前面 在软件开发中,有时候需要通过 Python 去监听指定区域文件或目录的创建、修改,或者删除,从而引发特定的事件处理。本篇博客为你介绍第三方模块 Watchdog 实现对文件事件的监控。 公众号: 滑翔的纸飞机 2. Watchdog 2…...

C++中多态的原理【精华】
虚函数表 通过一道题我们先感受一下编译器针对多态的处理 #include <iostream> using namespace std;class Base { public:virtual void Func1(){cout << "Func1()" << endl;} private:int _b 1;char _c };int main() {cout << sizeof(B…...

亿赛通电子文档安全管理系统 Update.jsp SQL注入
目录 0x01 漏洞介绍 0x02 影响产品 0x03 语法特征 0x04 漏洞复现页面 0x05 漏洞修复建议 0x01 漏洞介绍 亿赛通电子文档安全管理系统是国内最早基于文件过滤驱动技术的文档加解密产品之一,保护范围涵盖终端电脑(Windows、Mac、Linux系统平台&#…...

神经网络中的反向传播:综合指南
塔曼纳 一、说明 反向传播是人工神经网络 (ANN) 中用于训练深度学习模型的流行算法。它是一种监督学习技术,用于调整网络中神经元的权重,以最小化预测输出和实际输出之间的误差。 在神经网络中,反向传播是计算损失函数…...

协同创新、奔赴未来——“华为云杯”2023人工智能创新应用大赛华丽谢幕
9月27日,在苏州工业园区管理委员会、华为云计算技术有限公司的指导下,由SISPARK(苏州国际科技园)、华为(苏州)人工智能创新中心联合主办,东北大学工业智能与系统优化国家级前沿科学中心、浙江大…...

介绍Node.js中fs模块 代码和注释。
Node.js中的fs模块提供了一些用于文件系统操作的API,包括文件读写、目录操作等。 读取文件 使用fs.readFile()方法可以读取文件内容。该方法的第一个参数是文件路径,第二个参数是可选的选项对象,第三个参数是回调函数。回调函数的第一个参数…...

【QT 读取JSON】 深入浅出 使用QT内置的QJson模块解析Json文件 匠心之作
目录 0 引言1 Json数据分析2 解析Json数据 🙋♂️ 作者:海码007📜 专栏:QT专栏💥 标题:【QT 读取JSON】 使用QT内置的QJson模块解析Json文件❣️ 寄语:人生的意义或许可以发挥自己全部的潜力&…...

初识javaweb2 tomcat
如果是tomcat启动成功却无法通过localhost:8080进入页面,先去查看是否是端口号被占用, 再用命令中断占用的进程,如果简单的命令窗口无法中断,切换到管理员身份运行即可 netstat -ano|findstr "8080" 查看那个进程占用了…...

使用OPENROWSET :在一个数据库中查询另一个数据库的数据
当你需要在一个数据库中查询另一个数据库的数据时,SQL Server提供了多种方法来实现这一目标。一种常见的方法是使用链接服务器(Linked Server),另一种方法是使用 OPENROWSET 函数。本篇博客将重点介绍如何使用 OPENROWSET 函数在当…...

基于STM32设计的智慧农业管理系统(ESP8266+腾讯云微信小程序)
一、项目介绍 基于STM32设计的智慧农业控制系统(ESP8266+腾讯云微信小程序) 1.1 项目背景 随着人们对食品安全和生态环境的日益重视,智慧农业逐渐成为一个备受关注的领域。智能化管理可以提高农业生产效率,减少资源浪费,改善生态环境。因此,基于物联网技术的智慧农业管理系…...

Flutter视图原理之三棵树的建立过程
目录 三棵树的关系树的构建过程1.updateChild函数(element的复用)2.inflateWidget函数3.mount函数3.1 componentElement的实现3.2 RenderObjectElement的实现3.2.1 attachRenderObject函数 4.performRebuild函数 总结三棵树创建流程 三棵树的关系 Flutt…...

详细解析冒泡排序,JS如何基本实现的。
目录 冒泡排序是什么: 使用冒泡排序是为了什么: DEMO示例: 冒泡排序是什么: 冒泡排序(Bubble Sort)是一种简单的比较排序算法,它通过多次遍历待排序的元素,比较相邻元素的大小,如果它们的顺序不正确就交换它们&…...

如何消除CSDN博文代码中自动添加的行号
哪里有自定义目录标题 编写CSDN博文,使用代码块的linux命令行,预览时没有代码行号,但发布文章后自动添加了行号。 git clone https://github.com/mikel-brostrom/yolo_tracking.git cd yolo_tracking pip install -v -e .为什么预览和发布的…...

定制效果在线定制印刷系统源码 DIY在线定制系统源码 云印刷定制系统源码手机、PC端实时互通
支持各类产品的在线定制,无论是水杯雨伞U盘还是T恤衬衫四件套,均可轻松进行定制 独创制作间概念,同一套模板可以重复对应不同制作间 手机、PC端实时互通,客户可通过任意途径进行图片上传、编辑,一方修改另一方即时可见…...

算法|每日一题|同积元组|哈希统计
1726.同积元组 原题地址: 力扣每日一题:同积元组 给你一个由 不同 正整数组成的数组 nums ,请你返回满足 a * b c * d 的元组 (a, b, c, d) 的数量。其中 a、b、c 和 d 都是 nums 中的元素,且 a ! b ! c ! d 。 class Solution …...

最新AI创作系统ChatGPT网站H5源码V2.6.4+搭建部署教程+支持GPT4.0+支持ai绘画(Midjourney)/支持Prompt预设应用
一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统,支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…...

最新!两步 永久禁止谷歌浏览器 Google Chrome 自动更新
先放效果图: CSDN这个问题最火的大哥的用了没用 像他这样连浏览器都打不开 为什么要禁止chrome自动更新 看到很多搞笑的大哥,说为啥要禁止; 我觉得最大的原因就是chromedriver跟不上chrome的自动更新,导致我们做selenium爬虫的…...

在Java中线程和进程的区别
在Java中,线程和进程的区别与一般的操作系统环境下类似,但在Java语言层面上也有一些特点。下面是在Java中线程和进程的区别: 定义:在Java中,进程是指一个正在运行的应用程序实例,而线程是进程中的执行单元。…...

【高危安全通告】Oracle 10月月度安全漏洞预警
近日,安全狗应急响应中心关注到Oracle官方发布安全公告,共披露出在Oracle Weblogic中存在的6个高危漏洞。 漏洞描述 CVE-2023-22069:Oracle Weblogic 远程代码执行漏洞 Oracle WebLogic Server存在远程代码执行漏洞,该漏洞的CVS…...

卷王问卷考试系统SurveyKing,开源调查问卷和考试系统源码
卷王问卷考试系统/SurveyKing是一个功能最强大的开源调查问卷和考试系统,可以快速部署,并适用于各行业。该系统提供了在线表单设计、数据收集、统计和分析等功能,支持20多种题型,多种创建问卷方式和多种问卷设置。 无论您是需要进…...

uniapp开发微信小程序,webview内嵌h5,h5打开pdf地址,解决方案
根据公司要求,让我写一个h5,后续会嵌入到合作公司的微信小程序的webview中,如果是自己公司微信小程序,可以采取先下载下来pdf,然后通过wx.openDocument,进行单纯的预览操作,这个可以根据这个老哥…...

Swift使用Embassy库进行数据采集:热点新闻自动生成器
概述 爬虫程序是一种可以自动从网页上抓取数据的软件。爬虫程序可以用于各种目的,例如搜索引擎、数据分析、内容聚合等。本文将介绍如何使用Swift语言和Embassy库编写一个简单的爬虫程序,该程序可以从新闻网站上采集热点信息,并生成一个简单…...

【AIGC核心技术剖析】改进视频修复的传播和变压器(动态滤除环境中的物体)
基于流的传播和时空变压器是视频修复(VI)中的两种主流机制。尽管这些组件有效,但它们仍然受到一些影响其性能的限制。以前基于传播的方法在图像域或特征域中单独执行。与学习隔离的全局图像传播可能会由于光流不准确而导致空间错位。此外&…...

Win系统VMware虚拟机安装配置(二)
系统的安装得分两个步骤,第一步得配置一台电脑,选配 cpu,内存,磁盘,网卡等硬 件。第二步才是安装系统。 一、配置电脑 1、 进入 VMware 双击 VMware 图标,看到如下界面。 2、 自定义新的虚拟机 3、…...

基于枚举实现的观察者模式
文章目录 前言一、观察者1.定义一个观察者接口2.察者接口具体实现类 二、主题1.定义一个主题接口2.主题接口具体实现类 三、枚举维护观察者1.定义枚举类维护观察者 四、观察者模式测试1.定义观察者模式测试接口2.观察者模式测试运行结果 前言 本文介绍使用枚举的方式实现的观察…...

基于神经网络的图像识别研究
基于神经网络的图像识别是计算机视觉领域的一个热门研究方向,尤其是深度学习技术的兴起。以下是一些与基于神经网络的图像识别相关的关键主题和研究方向: 1. 卷积神经网络(CNN): CNN是图像识别领域最重要的神经网络之…...

基于SSM的工资管理系统
基于SSM的工资管理系统 开发语言:Java数据库:MySQL技术:SpringSpringMVCMyBatisVue工具:IDEA/Ecilpse、Navicat、Maven 系统展示 登录界面 管理员界面 通知公告 考勤管理 工资管理 请假管理 摘要 基于SSM(Spring、S…...

微服务负载均衡实践
概述 本文介绍微服务的服务调用和负载均衡,使用spring cloud的loadbalancer及openfeign两种技术来实现。 本文的操作是在微服务的初步使用的基础上进行。 环境说明 jdk1.8 maven3.6.3 mysql8 spring cloud2021.0.8 spring boot2.7.12 idea2022 步骤 改造Eu…...

php定时任务
PHP实现执行定时任务的几种思路详解_php 精准定时任务_我是高手高手高高手的博客-CSDN博客 1.Linux服务器上使用CronTab定时执行php 我们先从相对比较复杂的服务器执行php谈起。服务器上安装了php,就可以执行php文件,无论是否安装了nginx或Apache这样的…...

2.2 如何使用FlinkSQL读取写入到文件系统(HDFS\Local\Hive)
目录 1、文件系统 SQL 连接器 2、如何指定文件系统类型 3、如何指定文件格式 4、读取文件系统 4.1 开启 目录监控 4.2 可用的 Metadata 5、写出文件系统 5.1 创建分区表 5.2 滚动策略、文件合并、分区提交 5.3 指定 Sink Parallelism 6、示例_通过FlinkSQL读取kafk…...