# EZFileshare
**Repository Path**: megaobanana/ezfileshare
## Basic Information
- **Project Name**: EZFileshare
- **Description**: 你是一个喜欢把文件乖乖放在自己电脑里,不愿意交给云盘厂的本地储存爱好者吗?
你是否嫌搭建一个中心化文件储存的NAS很麻烦?
你是不是曾经找过其它局域网传输工具,但是它们要么有广告,要么不同时支持Windows/Android/Mac/Linux
——该项目是一个支持*增量*文件夹*发送的文件传输工具,意在解决上述不满
- **Primary Language**: Python
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-12-19
- **Last Updated**: 2025-08-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README

> 摘要:为弥补市面上没有能提供局域网内点对点文件夹传输功能的软件的空缺,作者设计了基于python,java与c++语言,能在Android,Windows,MacOS,Linux上部署的家用局域网文件夹传输软件“Transit”。该软件不仅实现了基本的文件夹传输功能,还在基础框架上实现了文件夹增量传输,集成了能通过浏览器上传下载文件的微型Http服务器,扩展了悬浮窗截图发送、剪贴板同步等与传输相关的便利功能。且该软件PC端运行核心仅为单个python脚本文件,在部分自带Python环境的Linux发行版中将部署成本降低到了最低,可以做到仅仅下载一个KB级的脚本就能实现软件基本的传输功能。
# 1.开发背景
随着我国人均收入不断提高、生活水平不断改善,人们开始在电子设备上拥有了更高的消费能力。同时由于科技产品极高的迭代速度,即便是普通的中产家庭,也可能同时拥有笔记本电脑、平板电脑、一部甚至多部手机。与此同时,随着互联网、信息技术的大力发展,有越来越多的云储存产品进入市场,以解决用户在自己的多个设备上无法同步数据的问题。使用云存储非常便捷,但是其体验与用户的网络通信质量相关联,并且用户的数据隐私权不在自己手中。设备制造商也为了方便用户,通常在系统中植入了文件传输助手,但是系统之间通常存在隔阂,如苹果的“Airdrop”功能与安卓中的“小米互传”无法相互通信,且其通常无法传输文件夹。技术能力较强的用户可以选择搭建家用NAS(Network Attached Storage网络附加存储),以作为家用储存服务器,它解决了上述问题,但是一般只能在家内使用且部署成本高。市面上有一些的局域网传输软件,但是它们有的不同时支持四大主流操作系统,有的启动速度慢、有广告,有的只能发送单个文件。基于上述不足,作者设计了一套局域网传输软件
作者推荐将该软件使用于下述场景:平时将与自己有关的文件与数据全部保存在一个文件夹中,而不是散落在各个设备、各个软件中(如各类网盘、各类社交软件的缓存),在各个设备上都可存有这个文件夹或这个文件夹部分的拷贝。在一个设备上对文件夹中的内容进行编辑后,就可以使用本项目所开发的软件“Transit”同步到其它设备中
# 2.软件安装/使用方法
| 操作系统 | 安装方法 |
| ----------- | ------------------------------------------------------------ |
| 安卓 | 安装app-release.apk |
| Windows | 运行Windows_installer.exe |
| MacOS/Linux | 没有安装过python,则需安装。完整安装依赖库后可运行transit.py。
( 若不想安装依赖库,则可运行含基本功能且发送与接收分离的无图形界面版本:console_receiver.py与console_sender.py ) |
**使用方法**主要分为三个步骤:
1. 收发双方都打开该软件
2. 发送方确认接收方IP地址
3. 发送方确认要发送的文件/文件夹
4. 点击发送
其中完成步骤2有2种方法:
1. 软件启动时会通过UDP广播技术自动搜索接收端,也可点击软件内的按钮重新搜索,虽然正常情况下使用这种方法都能正确搜索到接收端IP地址。但是在VPN、虚拟机类软件工作时会产生干扰,并且在连接校园网等公网时网关会屏蔽该类广播技术。
2. 手动输入接收端IP地址:在该软件启动时会显示本机的IP地址,在发送端点击对应按钮/命令框输入指令即可手动设置接收端的IP地址
完成步骤3的方法也多种多样、充分利用了各操作系统的特性:
| 操作系统 | 确认要发送的文件/文件夹的方法 |
| ----------- | ------------------------------------------------------------ |
| Android | 在分享菜单中选择本软件 |
| | 通过其它软件(如图库)选择 |
| | 通过软件内置的文件浏览器选择 |
| | 选择最近发送过的文件 |
| | 直接填写文件/文件夹路径 |
| Windows | 将文件拖拽入输入框中 |
| | 在文件的右键菜单中选择本软件 |
| | 利用Shift+C复制文件地址并黏贴进路径输入框 |
| Linux/MacOS | 通过各种方法复制到文件地址后黏贴进路径输入框 |
# 3.原理
## 3.1软件工作原理
### 3.1.1简要版本:
### 3.1.2完整版本:
| 发送模式1:基于最后编辑时间的增量发送 | 发送模式2:完整MD5校验式增量发送 |
| ------------------------------------- | -------------------------------- |
|  |  |
### 3.1.3发送模块原理
不管是基于Java的手机端,还是基于Python的电脑端,在用户填写完待发送文件的地址并点击发送后,都会创建一个用于发送的进程。
当进程启动后,会锁定发送按钮,以防止开启多个争夺资源的重复进程。发送逻辑没有被放在进程中,而是被提取成一个单独的函数,因为发送逻辑不止在用户显式地发送文件时被用到,在“快速传输截图”以及“文字发送”等功能中也会使用到相同的逻辑。
在这个发送函数中,会首先计算出待发送文件的MD5值,以作为验证传输完整性的依据。然后发送函数会尝试与接收端建立基于TCP协议的链接。TCP协议比起UDP协议更稳定,更适合发送大量数据,且协议内部已经包含了一层简易校验,提升了传输的准确性。在建立连接后,会尝试发送传输包头,数据结构如下:
* 1字节消息类型,t代表短消息,f代表文件
* 32字节的MD5值,以字符形式存储
* 4字节的无符号整形,用于描述这4字节之后的utf-8编码的文件名字符数
* utf-8编码的文件名
传输完包头后,会将文件内容切块后发送,每块大小100 KB。全部传输完毕后会发送包含特定字符的包尾。传输完毕后会等待接收端发送一个y字符,以表示接收端所校验的数据完整。若接收到n字符则表示数据不完整,未接收到该字符或检测到传输中止都被视作传输失败,出现上述三种情况时都应重新执行上述整个发送逻辑。
### 3.1.4接收模块原理
不管是基于Java的手机端,还是基于Python的电脑端,接收进程都会随着软件的启动而一直保持运行。在进程内会开启一个TCP服务器,当与发送端连接成功后则会进入接收逻辑。
接收进程一边将接收到的数据包合并进文件,一边将数据包送入MD5消化(Digest)函数。接收完毕后,会判断文件名是否属于软件预定义的一组特殊文件名。在图1中承载这些比对信息的文件会就被赋予这些特殊文件名,以实现与普通文件共享接收逻辑的同时,能够将其与普通的用户发送的文件进行区分。
若该文件名确实属于预定义特殊文件名,则会额外运行此文件名所对应的特殊算法。如接收到`.transit_folder_struct_date.json`时则会调用`compare_folder_date_based`函数,它会比较本地文件的最后编辑时间与此json文件中发送端文件的最后编辑时间,以分析哪些文件需要被发送,哪些需要进一步使用MD5值校验。
## 3.2Windows平台下的打包方法
Windows占全球家用计算机的74.1%,作为世界第一主流的的电脑操作系统,需要重点对其进行适配,而用户对软件的第一印象就是其安装的难易程度。考虑到大部分Windows用户没有事先安装过Python,因此需要在发行版中集成一个简单的Python运行环境。
这个集成的Python环境是直接从已经正常安装Python的电脑中复制出来的,然后通过学习各个组件的用途和试错找到哪些组件是可以被删除的,以减小体积.
但是即便拥有了运行环境,未事先安装过Python的用户也无法通过双击.py文件直接启动脚本,只能通过输入cmd命令先切换路径(`cd 目录`)设置环境变量(`set PATH=%~dp0python;%PATH%`)然后指定使用Python解释器运行.py脚本(`python transit.py`)。
这对于普通用户太繁琐了,因此需要创建一个快捷“启动器”。作者设计了三种启动入口文件:.vbs文件,.exe文件与.bat文件。
* 正常用户通常通过由双击.vbs文件的快捷方式加载上述三个指令,通过给ws.run函数加上vbhide参数,即可隐藏默认会弹出的不美观的“命令提示符”窗口。
* 但是.vbs启动文件无法被添加到Windows11的“开始菜单”,只有.exe类型的文件才能被添加到“开始菜单”。因此作者编译了一个与.vbs功能相同的.exe启动文件,但是由于能力有限,无法对.exe设置签名,因此部分用户的杀毒软件可能会误将其作为病毒删除,因此该入口仅作为附加入口,普通用户通过桌面的.vbs快捷方式启动软件即可。
* bat启动文件无法屏蔽“命令提示符”窗口,因此作为该软件的调试模式启动入口,软件运行时产生的调试信息会通过`print()`输出在“命令提示符”窗口中,而不是UI界面中。
最后,将上述Python运行环境、核心脚本、启动脚本全部打包为安装程序的编译器使用的是Innosetup,它易于使用且开源免费,编译出的安装程序简洁美观。
## 3.3适配安卓系统
Android占全球智能手机的70%,作为世界第一主流的的手机操作系统,必然需要对其进行适配。但是Python在安卓上的运行环境非常难以配置,况且就算能展示出于PC端相同的UI界面,其操作逻辑也不适合基于触摸屏幕的收集,因此需要使用Android Studio、基于Java为安卓完全重新设计,设计的MainActivity页面逻辑
其中,为了充分安卓作为手机操作系统的特性,该版本的Transit比PC版新增了两个功能。第一个功能是允许用户将刚刚接收的文件通过分享菜单继续“接力”到其它软件中,如微信;该功能也允许用户直接打开刚刚接收的文件,如安装接收到的.apk文件。第二个功能是悬浮窗发送功能,在使用手机观看网课,电脑记录电子笔记的时候,配合PC端Transit的自动黏贴图片功能,可以利用此悬浮窗截图功能快速传输截图到笔记软件中。在截图时还可以启用截图滤镜(如文档扫描滤镜)来将老师的板书截图扫描为对比度更强的白底黑字截图,以进一步优化用户体验。
## 3.4设计亮点
* 多语言支持:所有字符串常量都被提取到一个类中,而不是散落在脚本的各个角落。在类的__init__初始化方法中,程序会首先根据locale.getlocale()[0]提取用于所在的区域格式,若是中国则将字符串常量全部格式化为中文版本,若是其它地区则初始化为该语言对应的字符串版本,若是不受支持的地区,则一律初始化为英文。通过这种方式,能在保持单.py脚本特性的情况下实现多语言支持。目前仅支持中文与英文。
* 通过浏览器传输文件:虽然该项目立志于打破设备操作系统之间的隔阂,成为各大系统之间的一个传输媒介。但是对于部分市场占比较少或过时的操作系统仍不能运行python脚本,作者也固然没有精力像对待安卓系统一样,为这些系统开发对应的版本。因此为了对其提供兼容的传输方式,作者决定在软件中提供“通过浏览器传输文件”功能。传输双方只要其中一个能安装该软件“Transit”,打开此功能,此设备就能在固定端口上运行一个临时Http服务器。另一个无法安装“Transit”的设备只要输入该临时Http服务器的URL或者扫描编码了该URL的二维码就能访问该Http服务器提供的“上传”与“下载”网页服务,利用受绝大部分操作系统兼容的Html与Javascript语言进行文件传输。
* 发送接收分离的终端模式与基于Tkinter的UI模式:在某些服务器系统或嵌入式系统中,只能通过命令行终端访问系统,在这种情况下固然无法加载图形界面,因此作者为其专门开发了终端版本。同时为了模块化、便于部署、简化在纯文字环境下的交互逻辑,作者决定软件的发送逻辑与接收逻辑抽离开,最终将该软件的终端版本分为了两个:console_receiver.py与console_sender.py。对于普通用户,自然更乐意使用带有图形界面的软件。Python内置的Tkinter库十分轻量且跨平台,虽然编写较为困难,但是用其绘制UI能让该软件在保持单Python脚本特性的同时提供多系统下的兼容性。
* · 基于C++的运行加速模块:虽然Python具有语法清晰、跨平台的特性,但是面对计算密集型任务时有严重的效率问题。在软件推荐的使用场景中,发送端大部分运算量都集中在收集待发送文件夹中所有文件的最后编辑时间信息,接收端大部分运算量都集中在对比本地文件夹中所有文件的最后编辑时间。因此这两部分的逻辑作者使用C++重新编写,并使用Visual Studio编译为.exe。在软件运行时若发现安装目录中有该.exe就会使用该.exe代替这部分逻辑,若没有则运行原先的Python代码。使用这种方案则能在不改变单python脚本的特性下增加运行加速的扩展功能。值得注意的是,虽然发送与接收核心逻辑也运行频繁,但是在千兆有线网的条件下,瓶颈仍是网速而非python的执行速度,因此未开发这部分的运行加速模块。
# 4.附录
## 4.1依赖库
注:下述依赖库已经整合进Windows平台中的exe安装包,若在MacOS/Linux下则需安装下述依赖库
Windows平台:
```
首先运行pip install pywin32 pyperclip pillow pynput qrcode windows-toasts watchdog psutil
tkinterdnd2的安装比较麻烦,详见项目中的【tkdnd手动安装所需文件】文件夹,目前pip安装有问题,如果嫌烦可以不安装,不会导致程序无法运行,只是部分拖拽功能被屏蔽
```
Ubuntu平台:
```
首先运行sudo apt-get install python-tk安装tkinter,如果报错就用或sudo apt-get install python3-tk
然后运行sudo apt-get install python3-pil python3-pil.imagetk
然后运行sudo pip install pyperclip pillow pynput qrcode watchdog psutil
如果上面一句报错可以试试sudo pip install pyperclip pillow pynput qrcode watchdog psutil --break-system-package
最后安装sudo apt-get install xsel
```
## 4.2疑难解答
1. 如果出现无法自动搜索到IP地址时,可检查一下是否是由于 路由器禁用了UDP广播 / 安装了VPN或其它网络管理软件 / 虚拟机的虚拟网卡冲突 / 防火墙关闭
目前已知安装Radmin VPN会产生无法UDP广播的问题,可尝试在设备管理器->网络适配器中禁用Famatech Radmin VPN Ethernet Adapter
并且已知VMware的虚拟网卡也会产生干扰,同样需要在设备管理器里禁用虚拟网卡(不过这样虚拟机就上不了网了)
2. 推荐在虚拟机中使用桥接网络模式,不然可能无法在虚拟机和主机间通信
3. 若在Windows平台(特别是精简版)上出现任务栏被锁定的Bug,有可能是本软件产生的消息提醒(Toast)产生的,暂且不知道此Bug的根本原因,
但是可以通过在软件顶部的命令框中输入config打开配置文件,然后将"en_toast_message": 设置为false,来禁止软件发出消息提醒
4. 如果发送**超大量**文件(比如百G的数万小文件)时总出现莫名奇妙的无限断线重连,可能是由于网卡性能问题,操作系统等等奇怪的原因
( 据测试同一台电脑使用廉价usb迷你网卡会出现此问题而现代wifi6网卡不会,同一台电脑使用Ubuntu会有Bug而Windows没有 )
目前仅有一个不完善的解决方案,就是在每发送完一个文件后延迟一小段时间,可以通过在软件顶部的命令框中输入rest=0.2,即每发送一个文件延迟0.2秒
## 4.3代码引用
软件中截图图像增强部分借用了这个项目中的代码:https://github.com/ethereal-developers/OpenScan
软件中文件选择部分借用这个作者某个项目的代码:DarkRanger