我的第一个正式开源小项目:内网文件传输工具
内网文件传输工具
为什么开发?
- 单个大文件分发速度慢。一份大文件如果存在U盘里想要同时分发给多个人节省拷贝时间,我能想到的除了网盘和共享文件夹就没有其他的方法(可能是我见识太少了没啥思路。我也不喜欢用网盘传文件,问就是0充豹子头)
- 不同U盘拷贝速度不一样,况且需要同时给多个用户分发或者拷贝,还需要各种设备都需要能够访问到这个需求。说到这里我想到了把资源做种,但还是嫌麻烦,有些普通用户和电脑小白可能不大会使用一些磁力链接下载软件,主要是想即开即用,作为一个临时需求工具而不是长期使用的工具
- 为什么不做公网的文件分发?第一个是本来我也不太了解安全技术,公网想要传输超大文件还是比较吃硬件资源的,建议在公网传输一些大文件还是走端到端、网盘和磁力链接,避免被中间人劫持和篡改文件。当然内网传输也不是说在不可信网络的情况下去随便传文件啊,只是说大部分时候在内网传输都是可信网络,所以安全问题没怎么考虑过。项目里可能存在一些技术隐患比如XSS、SQL注入之类的,不过考虑到只是普通人在内网传输一般也都是熟人所以就没做这些预防工作😅
项目简介
这款工具基于Python开发,旨在提供一个简单、快速、安全的局域网文件共享方案。它拥有直观的Web界面,支持大文件分块上传、实时同步、跨平台运行,非常适合家庭和办公室环境。
GitHub仓库: https://github.com/MagicCD/Transfer (欢迎大家Star和Fork!)
核心功能
- 文件传输核心功能
- 大文件分块上传:当文件大于50MB时,自动启用分块上传,默认每个分块5MB,临时分块存储在
.temp_chunks
目录,上传完成后自动合并。 - 实时同步:使用Socket.IO实现双向通信,文件列表实时更新,上传进度实时显示。
- 文件管理:支持批量删除和清空操作,文件类型自动匹配图标。
- 大文件分块上传:当文件大于50MB时,自动启用分块上传,默认每个分块5MB,临时分块存储在
- 安全与优化
- 临时文件清理:自动清理超过2小时的临时分块。
- 安全配置:限制最大上传文件5GB。
- 界面交互
- 拖拽上传:支持直接拖拽文件到网页上传区域。
- 进度控制:提供上传进度条、暂停/恢复按钮。
- 文件管理:支持单文件删除和清空所有文件。
- 系统特性
- 跨平台支持:使用PyWebView封装浏览器窗口,支持所有Python支持的平台。
- 自动清理:定时任务每2小时清理过期临时文件。
- 大文件支持:分块上传+断点续传机制,支持5GB以内文件。
- 实时性:WebSocket实现实时文件列表更新(延迟<1秒)。
技术栈
- 后端:
- Flask (2.3.3):Web框架,处理HTTP请求。
- Flask-SocketIO (5.3.4):实时通信,推送文件列表更新。
- PyWebView (4.3):封装为桌面应用,提供窗口管理。
- Werkzeug (2.3.7):请求处理。
- schedule (1.2.0):定时任务。
- 前端:
- HTML5
- CSS3
- JavaScript
- Font Awesome:图标库。
运行环境
- Python版本:3.8 - 3.13
- 依赖库:见requirements.txt
快速上手
-
安装依赖
pip install -r requirements.txt
-
启动服务
python main.py
-
访问界面
- 自动打开桌面窗口,显示类似
http://192.168.1.100:5000
的内网地址。 - 支持拖拽上传和文件管理操作。
- 自动打开桌面窗口,显示类似
目录结构
├── static/
│ ├── js/ # 存放JavaScript文件
│ ├── app_icon.svg # 应用图标
│ └── style.css # 样式文件
│
├── templates/
│ └── index.html # Web界面模板
│
├── main.py # 应用入口文件
├── app.py # Flask应用核心逻辑
├── resource_path.py # 资源路径处理工具
└── README.md # 项目文档
核心代码片段
-
资源路径处理 (resource_path.py)
# filepath: e:\AI_Project\trae_AIproject\resource_path.py import os import sys def resource_path(relative_path): """获取资源的绝对路径,兼容开发环境和PyInstaller打包后的环境""" if hasattr(sys, '_MEIPASS'): # PyInstaller打包后的临时目录路径 base_path = sys._MEIPASS else: # 开发环境下的当前目录 base_path = os.path.abspath(".") return os.path.join(base_path, relative_path)
这个函数用于在开发环境和打包后的环境中都能正确找到资源文件。
-
文件图标映射 (app.py)
# filepath: e:\AI_Project\trae_AIproject\app.py icon_map = { '.mp4': 'fa-video', '.pdf': 'fa-file-pdf', '.py': 'fa-file-code', '.zip': 'fa-file-archive' }
通过文件后缀名匹配对应的Font Awesome图标。
-
分块上传处理 (app.py)
# filepath: e:\AI_Project\trae_AIproject\app.py @app.route('/upload/chunk', methods=['POST']) def upload_chunk(): # ... # 保存当前块 chunk_path = os.path.join(file_temp_dir, f"chunk_{chunk_number}") chunk.save(chunk_path) # 如果这是最后一个块,合并所有块 if chunk_number == total_chunks - 1: # 合并块 - 优化版本:流式写入,减少内存占用 final_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) with open(final_path, 'ab') as outfile: # 使用追加二进制模式 for i in range(total_chunks): chunk_file_path = os.path.join(file_temp_dir, f"chunk_{i}") if os.path.exists(chunk_file_path): with open(chunk_file_path, 'rb') as infile: # 逐块读写,减少内存占用 while True: data = infile.read(1024*1024) # 每次读取1MB if not data: break outfile.write(data) # ...
这段代码实现了大文件分块上传的核心逻辑,包括分块的保存和合并。
打包发布
项目支持通过PyInstaller打包为单文件可执行程序:
pyinstaller --onefile --windowed \
--add-data "templates;templates" \
--add-data "static;static" \
main.py
总结
项目目前处于开发阶段,距离完全可用可能还有一段时间,但基本上给小团体传传文件应该没什么问题🥲