Python 扫描监控本地文件夹并进行超大文件上传

  • 方案1:WebUploader大文件分块多线程并发上传
  • 方案2:watchdog目录文件夹监控,paramiko STFP上传服务器
  • 方案3:优化2,压缩后上传,服务器解压
    • (1)监控本地文件夹
    • (2)paramiko利用sftp连接远程服务器,并上传目录或者文件;
    • (3)源码
  • 参考

Python监控本地目录文件夹,并分块等方式上传文件到服务器

有几种思路:大文件分块上传,或者先压缩后上传在解压;

  • 目录监控方案: Java WatchEvent(可以监控到目录/文件的新建、修改、移动、删除)
    Python watchdog(同Java WatchEvent)
  • 大文件上传方案:WebUploader(h5+js)大文件分块,上传后在合并
    压缩后上传,在解压
    可以使用FTP、SFTP等连接服务器上传

方案1:WebUploader大文件分块多线程并发上传

WebUploader 是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。

集成了文件分块,异步多线程上传

原理:可设置是否分块、分块大小、是否多线程并发上传;
H5页面触发,js里可设置是否分块、分块大小、线程并发数;上传文件时,同一个文件会带有一个唯一的taskId,及当前分块数;上传结束后根据taskId调用回调函数合并文件;

分片与并发结合,将一个大文件分割成多块,并发上传,极大地提高大文件的上传速度。当网络问题导致传输错误时,只需要重传出错分片,而不是整个文件。另外分片传输能够更加实时的跟踪上传进度。

优点:支持分块并发上传,速度快;
缺点:需要h5页面触发(不适用于自动化)

方案2:watchdog目录文件夹监控,paramiko STFP上传服务器

watchdog 目录文件夹监控 可以监控到目录/文件的新建、修改、移动、删除;如下图;

监控到目录文件新增或者修改,可能有一个问题;就是某个文件很大,需要1分钟完全复制过来,但在第2秒已经监测到其新增,监测到其更新,一直持续到复制完;
可以通过捕获报错并sleep(10)在进行上传操作解决;

paramiko SFTP连接服务器直接上传文件

方案3:优化2,压缩后上传,服务器解压

watchdog目录文件夹监控
zip、unzip压缩上传后解压
paramiko SFTP连接服务器上传文件
该方案对方案2进行优化,增加了zip压缩文件,到服务器端在解压;

(1)监控本地文件夹

可以监听到文件 创建、更新、删除、重命名;

Python下用 win32file 或者 watchdog
Java下用 WatchEvent

无论是win32file、watchdog,监控到文件有更新时,大文件很可能还在更新状态,同时操作这个文件会报error;

如下图,对于大文件,当第一次监控到文件是新增或者修改,文件本身还未操作结束,检测到有变更立即处理就会有问题;

(2)paramiko利用sftp连接远程服务器,并上传目录或者文件;

  • 运用python:paramkio模块;
  • 安装:pin install paramkio

paramkio实现了ssh,用来操作文件(上传、删除);

  • paramkio 可以完成以下操作:
  1. 判断目录存在与否;
  2. 删除目录;
  3. 新建目录;
  4. 上传、下载文件;

(3)源码

监控本地文件夹,并上传其变更项(新增、修改及删除均进行同步)

有一个问题需要注意:当有新增时,会先检测到新增、然后检测到更新,如果文件比较大,会持续监控到一个文件的多个更新;操作时会报错,可以采用sleep(10)秒在操作;避免持续报错;

# argparse 命令行参数构建和解析
# watchdog 监控文件的变化
# sftp 上传文件到服务器
import argparse
import os
import time
from stat import S_ISDIRimport paramiko
from watchdog.events import *
from watchdog.observers import Observerimport log_exec_time# 监听目录及文件变化的类
class FileEventHandler(FileSystemEventHandler):def __init__(self):FileSystemEventHandler.__init__(self)def on_moved(self, event):if event.is_directory:print("directory moved from {0} to {1}".format(event.src_path, event.dest_path))else:print("file moved from {0} to {1}".format(event.src_path, event.dest_path))def on_created(self, event):if event.is_directory:print("directory created:{0}".format(event.src_path))else:print("file created:{0}".format(event.src_path))def on_deleted(self, event):if event.is_directory:print("directory deleted:{0}".format(event.src_path))rm(event.src_path)else:print("file deleted:{0}".format(event.src_path))rm(event.src_path)def on_modified(self, event):if event.is_directory:print("directory modified:{0}".format(event.src_path))# 只处理修改、删除的事情upload(event.src_path, remote_dir)else:print("file modified:{0}".format(event.src_path))uploadFile(event.src_path)# hostname = 'xxx.xxx.xxx.xxx'
# username = 'root'
# password = 'ffff'
# port = 22
# local_dir = 'D:/gifCreate/'
# remote_dir = '/data/home/mdir/'ap = argparse.ArgumentParser()
ap.add_argument("-host", "--hostname", required=False, default='xxx.xxx.xxx.xxx',help="the server host")
ap.add_argument("-username", "--username", required=False, default='root',help="ther server username")
ap.add_argument("-pwd", "--password", required=False, default='fffff',help="ther server password")
ap.add_argument("-port", "--port", required=False, default=22,help="ther server port")
ap.add_argument("-localdir", "--localdir", required=False, default='D:/gifCreate/',help="path of the localdir")
ap.add_argument("-remotedir", "--remotedir", required=False, default='/data/home/mdir/',help="ther server remotedir")
args = vars(ap.parse_args())hostname = args['hostname']
username = args['username']
password = args['password']
port = args['port']
local_dir = args['localdir']
remote_dir = args['remotedir']def isdir(path):try:t = paramiko.Transport((hostname, port))t.connect(username=username, password=password)sftp = paramiko.SFTPClient.from_transport(t)return S_ISDIR(sftp.stat(path).st_mode)except IOError as e:return Falsedef rm(path):try:t = paramiko.Transport((hostname, port))t.connect(username=username, password=password)sftp = paramiko.SFTPClient.from_transport(t)path = path.replace('\\', '/').replace(local_dir, remote_dir).replace('\\', '/')if not isdir(path):sftp.remove(path)print('\t%s deleted.' % path)returnprint(path)files = sftp.listdir(path=path)for f in files:filepath = os.path.join(path, f)if isdir(filepath):rm(filepath)else:sftp.remove(filepath)print('\t%s deleted.' % path)sftp.rmdir(path)print('\t%s dir deleted.' % path)except Exception as e:print(e)@log_exec_time.log_execution_time
def upload(local_dir, remote_dir):try:t = paramiko.Transport((hostname, port))t.connect(username=username, password=password)sftp = paramiko.SFTPClient.from_transport(t)for root, dirs, files in os.walk(local_dir):for name in dirs:# print(name)# 过滤掉图片文件夹if (str(name) == 'Img'):continuelocal_path = os.path.join(root, name)a = local_path.replace(local_dir, '').replace('\\', '/').replace('\\', '/')remote_path = remote_dir + a# print('dir: %s,dirname: %s' % (a, name))try:sftp.mkdir(remote_path)print("mkdir path %s" % remote_path)except Exception as e:print("dir path is exists: %s" % remote_path)for filepath in files:# 过滤掉图片if (filepath.endswith('.jpg') or filepath.endswith('.JPG') or filepath.endswith('.JPEG')):continuelocal_file = os.path.join(root, filepath)a = local_file.replace(local_dir, '').replace('\\', '/').replace('\\', '/')remote_file = remote_dir + a# print('\tlocal_file: %s,  filepath: %s' % (local_file, filepath))try:sftp.put(local_file, remote_file)except Exception as e:sftp.mkdir(os.path.split(remote_file)[0])sftp.put(local_file, remote_file)# print("upload %s to remote %s" % (local_file, remote_file))# print('upload file success %s ' % datetime.datetime.now())t.close()except Exception as e:print(e)@log_exec_time.log_execution_time
def uploadFile(filepath):remote_file = filepath.replace('\\', '/').replace(local_dir, remote_dir).replace('\\', '/')# print(remote_file)try:if not os.path.exists(filepath):print('error: %s not exists' % filepath)returnt = paramiko.Transport((hostname, port))t.connect(username=username, password=password)sftp = paramiko.SFTPClient.from_transport(t)try:# print(filepath)sftp.put(filepath, remote_file)except Exception as e:sftp.mkdir(os.path.split(remote_file)[0])sftp.put(filepath, remote_file)# print(e)if (e == '[Errno 2] No such file'):print('error: %s' % e)# print(e)print('uploadFileSuccess: %s' % filepath)t.close()except Exception as e:time.sleep(10)uploadFile(filepath)# print('e1: %s' % e)if __name__ == '__main__':# 1.88G  630s  10 mins 30 s# 18G  2.1hprint(args)print("Paramaters:")print("hostname: " + hostname)print("username: " + username)print("password: " + password)print("port: " + str(port))print("local_dir: " + local_dir)print("remote_dir: " + remote_dir)# 上传原始目录upload(local_dir, remote_dir)# 监控目录,有文件变化时及时处理observer = Observer()event_handler = FileEventHandler()observer.schedule(event_handler, local_dir, True)observer.start()try:while True:time.sleep(1)except KeyboardInterrupt:observer.stop()observer.join()

参考

  • Python 监控本地文件夹
  • Java 监控本地文件夹
  • Java 监控某个目录下的文件
  • Python paramkio 利用ssh连接远程服务器,并上传目录或者文件;
  • Python 使用SFTP删除远程目录
  • Python WebUploader超大文件并发分块上传

Python监控目录文件夹,并使用SFTP上传目录及文件到linux服务器相关推荐

  1. 如何在Linux中使用sFTP上传或下载文件与文件夹

    如何在Linux中使用sFTP上传或下载文件与文件夹 sFTP(安全文件传输程序)是一种安全的交互式文件传输程序,其工作方式与 FTP(文件传输协议)类似. 然而,sFTP 比 FTP 更安全;它通过 ...

  2. 服务器监控文件变化,如何使用nodejs监控文件变化并使用sftp上传到服务器

    如何使用nodejs监控文件变化并使用sftp上传到服务器 发布时间:2021-07-01 12:06:56 来源:亿速云 阅读:99 作者:小新 这篇文章主要为大家展示了"如何使用node ...

  3. node 自动上传文件到服务器,利用nodejs监控文件变化并使用sftp上传到服务器

    最近在用react+express做一个自己的工具型网站(其实就是夺宝岛抢拍器) 然后因为经常要改动,而且又要放到服务器上进行测试.总是要webpack,然后手动把文件上传上去,不胜其烦,索性搜索了下 ...

  4. 在Ubuntu终端使用mkdir创建文件夹后Xftp不能上传文件到文件夹中的问题解决方法

    问题描述 在Ubuntu终端上使用mkdir创建文件夹后使用Xftp上传文件失败 原因分析: 权限问题 解决方案: chmod 777 File

  5. java ssh 服务器文件传输_java使用SFTP上传文件到资源服务器

    本文实例为大家分享了java实现SFTP上传文件到资源服务器工具类,供大家参考,具体内容如下 首先得创建连接sftp服务器的公共类MySftp.java: package cn.test.util; ...

  6. MacOS下载服务器的文件/文件夹到本地、上传本地文件到服务器

    1.从服务器下载文件或文件夹 如果要下载xx.cpp文件,则在本地终端输入: scp 用户名@主机名:xx/xxx/xx.cpp 本地路径 如果要下载dir文件夹,则在本地终端输入: scp -r 用 ...

  7. 码云上传文件夹_码云上传本地文件夹,码云只能上传20个文件的突破方法

    码云官方地址:https://gitee.com/ 很多人不知道码云上传本地文件夹怎么操作,或者如何突破码云只能上传20个文件限制的问题,今天就来说说这事的方法吧. 简介: 码云是媲美GitHub的代 ...

  8. vue对文件夹进行拖拽上传完整流程(文件夹中超出100个文件)

    前言 上个文章介绍了多图片压缩,多图片可以通过直接多选图片进行拖拽,也可以通过直接拖拽文件夹进行解析得到多图片,接下来直接上代码 先展示文件拖拽后对文件的解析效果 图片文件夹 图片文件夹解析 大文件夹 ...

  9. java的sftp文件传输_java使用SFTP上传文件到资源服务器方法详解

    java使用SFTP上传文件到资源服务器 本文实例为大家分享了java实现SFTP上传文件到资源服务器工具类,供大家参考,具体内容如下 首先得创建连接sftp服务器的公共类MySftp.java: p ...

最新文章

  1. 瞬间学会使用java中list的retainAll方法
  2. Source insight关联QT库函数
  3. android 代码 日历 重复事件设置,日历重复/重复事件 - 最佳存储方法
  4. LSTM 和 GRU
  5. 在网页中嵌入flash之标签
  6. php怎么设置网站的字符编码,php如何设置字符编码
  7. C#设计模式之5-单例模式
  8. Huaman Gene Functions
  9. 95-40-150-java.util.concurrent-ExecutorCompletionService
  10. Kali linux 渗透测试(五)——渗透WPS攻击
  11. 项目管理十大过程思维导图
  12. ​LeetCode刷题实战507:完美数
  13. 未转变者服务器bug,未转变者攻略 unturned无敌BUG说明
  14. GAN系列学习(1)——前生今世
  15. python复制word中的内容,包括格式、图片、文字
  16. Matlab图片预处理——截取图片中有效部分保存在其余文件夹下
  17. arduino学习笔记十八--红外遥控检测
  18. [CEOI2017]One-Way Streets
  19. Xshell6 提示要继续使用此程序,您必须应用最新的更新或使用新版本
  20. 【神奇的电报】CSP题目 C++实现

热门文章

  1. Can't add more than 2 views to a ViewSwitcher
  2. Android intent 接受值的内容为空
  3. 2019春第二次课程设计实验报告
  4. 小程序navigateBack,子页面传值给父页面
  5. IP白名单添加了当前IP,获取access_token时依然报出错误码40164的坑
  6. Django框架(十)--常用字段、参数、元信息、多对多关联关系
  7. Go 学习笔记(26)— Go 习惯用法(多值赋值,短变量声明和赋值,简写模式、多值返回函数、comma,ok 表达式、传值规则)
  8. 使程序在后台执行,并将日志输出至文件
  9. 使用javascript模拟常见数据结构(二)
  10. 【iOS开发】企业版证书($299)In-House方式发布指南 (转)