当前位置: 首页 > 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;多种创建问卷方式和多种问卷设置。 无论您是需要进…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...