当前位置: 首页 > news >正文

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 漏洞介绍 亿赛通电子文档安全管理系统是国内最早基于文件过滤驱动技术的文档加解密产品之一&#xff0c;保护范围涵盖终端电脑&#xff08;Windows、Mac、Linux系统平台&#…...

神经网络中的反向传播:综合指南

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

协同创新、奔赴未来——“华为云杯”2023人工智能创新应用大赛华丽谢幕

9月27日&#xff0c;在苏州工业园区管理委员会、华为云计算技术有限公司的指导下&#xff0c;由SISPARK&#xff08;苏州国际科技园&#xff09;、华为&#xff08;苏州&#xff09;人工智能创新中心联合主办&#xff0c;东北大学工业智能与系统优化国家级前沿科学中心、浙江大…...

介绍Node.js中fs模块 代码和注释。

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

【QT 读取JSON】 深入浅出 使用QT内置的QJson模块解析Json文件 匠心之作

目录 0 引言1 Json数据分析2 解析Json数据 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;QT专栏&#x1f4a5; 标题&#xff1a;【QT 读取JSON】 使用QT内置的QJson模块解析Json文件❣️ 寄语&#xff1a;人生的意义或许可以发挥自己全部的潜力&…...

初识javaweb2 tomcat

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

使用OPENROWSET :在一个数据库中查询另一个数据库的数据

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

基于STM32设计的智慧农业管理系统(ESP8266+腾讯云微信小程序)

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

Flutter视图原理之三棵树的建立过程

目录 三棵树的关系树的构建过程1.updateChild函数&#xff08;element的复用&#xff09;2.inflateWidget函数3.mount函数3.1 componentElement的实现3.2 RenderObjectElement的实现3.2.1 attachRenderObject函数 4.performRebuild函数 总结三棵树创建流程 三棵树的关系 Flutt…...

详细解析冒泡排序,JS如何基本实现的。

目录 冒泡排序是什么: 使用冒泡排序是为了什么: DEMO示例: 冒泡排序是什么: 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的比较排序算法&#xff0c;它通过多次遍历待排序的元素&#xff0c;比较相邻元素的大小&#xff0c;如果它们的顺序不正确就交换它们&…...

如何消除CSDN博文代码中自动添加的行号

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

定制效果在线定制印刷系统源码 DIY在线定制系统源码 云印刷定制系统源码手机、PC端实时互通

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

算法|每日一题|同积元组|哈希统计

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

最新AI创作系统ChatGPT网站H5源码V2.6.4+搭建部署教程+支持GPT4.0+支持ai绘画(Midjourney)/支持Prompt预设应用

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…...

最新!两步 永久禁止谷歌浏览器 Google Chrome 自动更新

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

在Java中线程和进程的区别

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

【高危安全通告】Oracle 10月月度安全漏洞预警

近日&#xff0c;安全狗应急响应中心关注到Oracle官方发布安全公告&#xff0c;共披露出在Oracle Weblogic中存在的6个高危漏洞。 漏洞描述 CVE-2023-22069&#xff1a;Oracle Weblogic 远程代码执行漏洞 Oracle WebLogic Server存在远程代码执行漏洞&#xff0c;该漏洞的CVS…...

卷王问卷考试系统SurveyKing,开源调查问卷和考试系统源码

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

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...