Gopeed BT 下载路径配置手册:3 步修正保存位置
【免费下载链接】gopeedA fast, modern download manager for HTTP, BitTorrent, Magnet, and ed2k. Cross-platform, built with Golang and Flutter.项目地址: https://gitcode.com/GitHub_Trending/go/gopeed
把一个大种子拖进 Gopeed,下载完成后你打开"下载"目录,发现文件躺在Downloads/种子名/子目录/...的深处,而你明明只想让它存到 D 盘。Gopeed 的 BT 下载路径由创建任务时的opts.Path决定:不指定就落到全局downloadDir,之后无法事后搬动——所以控制路径的关键动作发生在任务创建前。
先对号入座:按症状找到方案档位
| 现象 | 可能原因 | 对应方案档位 |
|---|---|---|
新任务都存到了Downloads/目录 | 没设过默认下载目录,任务Path为空时回落到downloadDir | 档位 A:UI 设置默认目录 |
| 多文件种子的文件多套了一层"种子名"文件夹 | 这是 BT 协议的标准行为:多文件种子以种子名为根目录 | 档位 A:创建时选单文件,或接受该结构 |
指定目录创建任务报download directory is not in white list | 启用了whiteDownloadDirs白名单,你的目录不在匹配范围内 | 档位 B:把目录加进白名单 |
| 换过默认目录后,老任务还存旧位置 | 路径在任务创建时已固化到opts.Path,改默认值不影响存量任务 | 新任务重新指定目录 |
| 只下了部分文件,但种子名文件夹里还留着空壳目录 | 完成时 Gopeed 会删掉未选文件,但不会删目录本身 | 手动清理,或见档位 C 的定制思路 |
| 想按文件类型(视频/音频)分目录存放 | 默认逻辑只认"下载目录/种子名/文件路径"三段,没有分类能力 | 档位 C:改源码里的TorrentDirMaker |
根因三问:路径到底由谁决定
问一:任务不指定目录时,落在哪里?
每个任务创建前都会过一遍 pkg/download/downloader.go 里的initOptions。逻辑只有三步:Path为空就取全局downloadDir;然后做一次日期占位符替换;最后如果配置了白名单,用 glob 匹配校验,不通过直接拒绝建任务。
if opts.Path == "" { opts.Path = storeConfig.DownloadDir } opts.Path = util.ReplacePathPlaceholders(opts.Path) // WhiteDownloadDirs 非空时 filepath.Match 不通过 => 任务创建失败这也解释了第二行占位符的价值:downloadDir里写D:/gopeed/%year%/%month%,2026 年 9 月建的任务会自动落进D:/gopeed/2026/09,这是 pkg/util/path.go 中ReplacePathPlaceholders支持的写法。
问二:为什么多文件种子会多一层文件夹?
BT 任务启动时,Gopeed 把任务的Path交给 anacrolix 库的存储层,见 internal/protocol/bt/fetcher.go 的addTorrent:
spec.Storage = storage.NewFileOpts(storage.NewFileClientOpts{ ClientBaseDir: cfg.DataDir, TorrentDirMaker: func(baseDir string, info *metainfo.Info, infoHash metainfo.Hash) string { return f.meta.Opts.Path }, })TorrentDirMaker决定了这个种子所有文件的根目录,Gopeed 的选择就是opts.Path本身。库的约定是:多文件种子在根目录下先建一个与种子同名的文件夹,再按种子内部目录结构展开;单文件种子则直接以文件形式放在根目录下。你看到的下载目录/种子名/...就是这么来的,它不是 bug。
问三:为什么只选部分文件,剩下的也会消失?
多选下载只Download了SelectFiles命中的文件。任务完成后 internal/protocol/bt/fetcher.go 的Wait会轮询一次,把没选中的文件从磁盘清掉:
if !selected { util.SafeRemove(filepath.Join(f.meta.Opts.Path, f.meta.Res.Name, file.Path())) }所以"没下完的文件"不会白占空间,但种子名文件夹和空目录会留下来,这是磁盘上最后的残留。
分档方案:从 UI 到源码的三档改法
档位 A:免代码快速修复
适用条件:只想改默认保存位置、按任务挑目录,不改任何配置。
- 打开设置页,把默认下载目录改到你想用的盘(Android 上会回落到外部存储目录)。
- 创建 BT 任务时,在文件选择界面用目录选择器为单个任务指定路径——这个路径会写进任务的
opts.Path,优先级高于默认目录。 - 验证:任务详情页显示的路径就是你设置的路径;完成后在目标目录看到"种子名"文件夹(多文件)或裸文件(单文件)。
档位 B:配置级调整
适用条件:Web/API 部署(gopeed api/gopeed web),需要默认目录、目录白名单或按日期归档。
默认配置文件是
./config.json(可用-c改路径),修改位置见 cmd/web/flags.go。下载相关字段在downloadConfig里:{ "downloadDir": "D:/gopeed/%year%/%month%", "whiteDownloadDirs": ["D:/gopeed/*", "E:/media/*"] }也可以用命令行直接传:
-w "D:/a, E:/b"设置白名单,-d设置 Gopeed 自身的存储目录(日志、任务数据库所在处,与下载目录是两回事)。环境变量
GOPEED_DOWNLOADCONFIG可传整段 JSON(如{"downloadDir": "/env/downloads"}),适合容器部署。验证:白名单开启后,向非白名单目录建任务应立刻收到
download directory is not in white list报错;命中D:/gopeed/*这类带*的模式则放行。注意白名单是 glob 模式匹配,写D:/gopeed(不带/*)只放行这一个精确路径。
档位 C:源码级改造
适用条件:默认结构满足不了,例如"所有视频种子统一存到下载目录/BT-视频/"。需要自行编译(仓库地址 https://gitcode.com/GitHub_Trending/go/gopeed ,git clone后按项目文档构建)。
改动点只有一处——internal/protocol/bt/fetcher.go 里的TorrentDirMaker,把固定的f.meta.Opts.Path换成你自己的规则:
TorrentDirMaker: func(baseDir string, info *metainfo.Info, infoHash metainfo.Hash) string { // 例:按 info.Name 判断类别,统一归入 BT-视频 子目录 return filepath.Join(f.meta.Opts.Path, "BT-视频") }配合 internal/protocol/bt/config.go 的config结构(现有字段:listenPort、trackers、seedKeep、seedRatio、seedTime),可以加一个TypeDirs map[string]string字段,用扩展名查表决定子目录。改完重新编译,建一个新任务验证:文件应出现在下载目录/BT-视频/种子名/...,且旧任务不受影响。
配置速查
| 配置项 | 默认值 | 作用 | 修改位置 |
|---|---|---|---|
downloadDir | 空(Web 服务回落到存储目录旁的Downloads) | 新任务未指定Path时的保存目录,支持%year%等占位符 | config.json 的downloadConfig,或 UI 设置页 |
whiteDownloadDirs | 空(不校验) | 下载目录白名单,glob 模式匹配,不命中则拒绝建任务 | config.json,或 CLI-w "dir1,dir2" |
storageDir(CLI-d) | 可执行文件旁的storage | Gopeed 自身数据目录:日志、任务数据库,不是下载目录 | 启动参数-d |
listenPort | 0(由 BT 库自选) | BT 监听端口 | config.json 的protocolConfig |
seedKeep/seedRatio/seedTime | false/0/0 | 下载完成后是否继续做种及条件 | config.json 的protocolConfig |
selectFiles(任务参数) | 全部文件 | 多文件种子只下载指定索引的文件,其余完成时清理 | 创建任务请求或 UI 文件勾选 |
三个容易踩的坑
白名单是filepath.Match模式匹配而不是前缀判断,想放行整棵子树记得写D:/gopeed/*,参考 pkg/download/downloader.go 的校验逻辑。
路径在任务创建时固化进opts.Path,改默认目录或白名单都不会搬动已建任务的文件,目录规划要在建任务前想清楚。
storageDir和downloadDir是两个目录:前者放 Gopeed 的日志和数据库,后者才是你的文件,见 cmd/web/flags.go 的参数说明。
【免费下载链接】gopeedA fast, modern download manager for HTTP, BitTorrent, Magnet, and ed2k. Cross-platform, built with Golang and Flutter.项目地址: https://gitcode.com/GitHub_Trending/go/gopeed
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考