Skip to content

Commit efe25a3

Browse files
authored
Merge pull request #265 from dromara/dev
Release:2.2.0
2 parents 7503336 + 84a3d8d commit efe25a3

File tree

90 files changed

+6491
-413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+6491
-413
lines changed

README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ Amazon S3、GoogleCloud Storage、FastDFS、 Azure Blob Storage、Cloudflare R2
4444

4545
💡 通过 WebDAV 连接到 Alist 后,可以使用百度网盘、天翼云盘、阿里云盘、迅雷网盘等常见存储服务,查看 [Alist 支持的存储平台](https://alist.nn.ci/zh/guide/webdav.html#webdav-%E5%AD%98%E5%82%A8%E6%94%AF%E6%8C%81)
4646

47+
🚚 支持在不同存储平台之间迁移文件,详情查看 [迁移文件](https://x-file-storage.xuyanwu.cn/#/迁移文件)
48+
4749
GitHub:https://github.com/dromara/x-file-storage
4850
<br />
4951
Gitee:https://gitee.com/dromara/x-file-storage
@@ -54,6 +56,8 @@ Gitee:https://gitee.com/dromara/x-file-storage
5456

5557
这里是简要的更新记录,查看 [详细的更新记录](https://x-file-storage.xuyanwu.cn/#/更新记录)
5658

59+
`2.2.0` 修复大量问题,新增获取文件、列举文件,重构预签名 URL 支持客户端上传、下载、删除等操作,新增 Solon 插件,优化手动分片上传等功能,详情查看 [更新记录](https://x-file-storage.xuyanwu.cn/#/更新记录?id=_220)
60+
<br />
5761
`2.1.0` 修复大量问题,新增存储平台 FastDFS 和 Azure Blob Storage,新增复制、移动(重命名)文件,手动分片上传(断点续传)和计算哈希等功能,详情查看 [更新记录](https://x-file-storage.xuyanwu.cn/#/更新记录?id=_210)
5862
<br />
5963
`2.0.0` 捐赠至 [dromara](https://dromara.org/zh) 开源社区,更改项目名、包名,优化项目结构、支持 Metadata 元数据等,从旧版升级需要注意,详情查看 [更新记录](https://x-file-storage.xuyanwu.cn/#/更新记录?id=_200)
@@ -71,11 +75,13 @@ Gitee:https://gitee.com/dromara/x-file-storage
7175
### 📅更新计划
7276

7377
- 接入存储平台:HDFS、火山云 TOS、Samba、NFS
74-
- 用户端直传
7578
- 追加缩略图
76-
- 列出文件
7779
- 文件内容预加载
7880
- 新增 Access 模块,尝试通过 HTTP、FTP、WebDAV 等协议对外提供接口,方便其它程序使用
81+
- 追加文件
82+
- 分片下载
83+
- 直接输出到 HttpServletResponse 的响应流中
84+
- 其它更多功能
7985

8086
-------
8187

@@ -85,14 +91,14 @@ Gitee:https://gitee.com/dromara/x-file-storage
8591

8692
#### 🔧 配置
8793

88-
这里以阿里云 OSS 为例,`pom.xml` 引入本项目,这里默认是 `SpringBoot` 环境,其它环境参考 [脱离 SpringBoot 单独使用](https://x-file-storage.xuyanwu.cn/#/脱离SpringBoot单独使用)
94+
这里以阿里云 OSS 为例,`pom.xml` 引入本项目,这里默认是 `SpringBoot` 环境,`Solon` 环境参考 [在 Solon 中使用](https://x-file-storage.xuyanwu.cn/#/在Solon中使用)其它环境参考 [脱离 SpringBoot 单独使用](https://x-file-storage.xuyanwu.cn/#/脱离SpringBoot单独使用)
8995

9096
```xml
9197
<!-- 引入本项目 -->
9298
<dependency>
9399
<groupId>org.dromara.x-file-storage</groupId>
94100
<artifactId>x-file-storage-spring</artifactId>
95-
<version>2.1.0</version>
101+
<version>2.2.0</version>
96102
</dependency>
97103
<!-- 引入 阿里云 OSS SDK,如果使用其它存储平台,就引入对应的 SDK -->
98104
<dependency>
@@ -138,7 +144,7 @@ public class SpringFileStorageTestApplication {
138144
```
139145
#### ✨开始上传
140146

141-
支持 File、MultipartFile、byte[]、InputStream、URL、URI、String、HttpServletRequest,大文件会自动分片上传。如果想支持更多方式,请阅读 [文件适配器](https://x-file-storage.xuyanwu.cn/#/文件适配器) 章节
147+
支持 File、MultipartFile、UploadedFile、byte[]、InputStream、URL、URI、String、HttpServletRequest,大文件会自动分片上传。如果想支持更多方式,请阅读 [文件适配器](https://x-file-storage.xuyanwu.cn/#/文件适配器) 章节
142148

143149
```java
144150
@RestController
@@ -163,6 +169,7 @@ public class FileDetailController {
163169
public String upload2(MultipartFile file) {
164170
FileInfo fileInfo = fileStorageService.of(file)
165171
.setPath("upload/") //保存到相对路径下,为了方便管理,不需要可以不写
172+
.setSaveFilename("image.jpg") //设置保存的文件名,不需要可以不写,会随机生成
166173
.setObjectId("0") //关联对象id,为了方便管理,不需要可以不写
167174
.setObjectType("0") //关联对象类型,为了方便管理,不需要可以不写
168175
.putAttr("role","admin") //保存一些属性,可以在切面、保存上传记录、自定义存储平台等地方获取使用,不需要可以不写

docs/Metadata.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,22 @@ FileInfo fileInfo = fileStorageService.of(file)
1818
.putThUserMetadata("role","777")
1919
.thumbnail()
2020
.upload();
21+
22+
//获取
23+
RemoteFileInfo info = fileStorageService.getFile(fileInfo);
24+
Assert.notNull(info, "文件不存在");
25+
//文件元数据
26+
MapProxy metadata = info.getKebabCaseInsensitiveMetadata();
27+
//文件用户元数据
28+
MapProxy userMetadata = info.getKebabCaseInsensitiveUserMetadata();
2129
```
2230

2331
> [!WARNING|label:重要提示:]
2432
> 每个存储平台支持的 Metadata 有所不同,例如 七牛云 Kodo 和 又拍云 USS 就不支持 `Content-Disposition`,具体支持情况以每个存储平台的官方文档为准
2533
>
2634
> 在传入 UserMetadata 时,不用传入前缀,例如 `x-amz-meta-` `x-qn-meta-` `x-upyun-meta-`,SDK会自动处理
35+
>
36+
> 每个存储平台获取到的 Metadata 都不相同,有些是字符串类型,有些是其它类型的对象,这部分需要自行做好判断
2737
2838

2939
## 处理异常

docs/README.md

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Amazon S3、GoogleCloud Storage、FastDFS、 Azure Blob Storage、Cloudflare R2
4545

4646
💡 通过 WebDAV 连接到 Alist 后,可以使用百度网盘、天翼云盘、阿里云盘、迅雷网盘等常见存储服务,查看 [Alist 支持的存储平台](https://alist.nn.ci/zh/guide/webdav.html#webdav-%E5%AD%98%E5%82%A8%E6%94%AF%E6%8C%81)
4747

48+
🚚 支持在不同存储平台之间迁移文件,详情查看 [迁移文件](迁移文件)
49+
4850
GitHub:https://github.com/dromara/x-file-storage
4951
<br />
5052
Gitee:https://gitee.com/dromara/x-file-storage
@@ -55,6 +57,8 @@ Gitee:https://gitee.com/dromara/x-file-storage
5557

5658
这里是简要的更新记录,查看 [详细的更新记录](更新记录)
5759

60+
`2.2.0` 修复大量问题,新增获取文件、列举文件,重构预签名 URL 支持客户端上传、下载、删除等操作,新增 Solon 插件,优化手动分片上传等功能,详情查看 [更新记录](更新记录?id=_220)
61+
<br />
5862
`2.1.0` 修复大量问题,新增存储平台 FastDFS 和 Azure Blob Storage,新增复制、移动(重命名)文件,手动分片上传(断点续传)和计算哈希等功能,详情查看 [更新记录](更新记录?id=_210)
5963
<br />
6064
`2.0.0` 捐赠至 [dromara](https://dromara.org/zh) 开源社区,更改项目名、包名,优化项目结构、支持 Metadata 元数据等,从旧版升级需要注意,详情查看 [更新记录](更新记录?id=_200)
@@ -72,11 +76,13 @@ Gitee:https://gitee.com/dromara/x-file-storage
7276
# 📅更新计划
7377

7478
- 接入存储平台:HDFS、火山云 TOS、Samba、NFS
75-
- 用户端直传
7679
- 追加缩略图
77-
- 列出文件
7880
- 文件内容预加载
7981
- 新增 Access 模块,尝试通过 HTTP、FTP、WebDAV 等协议对外提供接口,方便其它程序使用
82+
- 追加文件
83+
- 分片下载
84+
- 直接输出到 HttpServletResponse 的响应流中
85+
- 其它更多功能
8086

8187
-------
8288

@@ -86,6 +92,32 @@ Gitee:https://gitee.com/dromara/x-file-storage
8692

8793
-------
8894

95+
# 💳捐赠
96+
如果你觉得这个项目不错,可以点个 Star 或捐赠请作者吃包辣条~,不想打赏的话用支付宝扫最后一个码可以领取个红包,在此表示感谢^_^
97+
98+
<img src="https://x-file-storage.xuyanwu.cn/assets/wx.png" style="height: 350px;margin-right: 20px" alt="微信">
99+
<img src="https://x-file-storage.xuyanwu.cn/assets/zfb.jpg" style="height: 350px;margin-right: 20px" alt="支付宝">
100+
<img src="https://x-file-storage.xuyanwu.cn/assets/zfb2.jpg" style="height: 350px" alt="支付宝2">
101+
<img src="https://x-file-storage.xuyanwu.cn/assets/elm.jpg" style="height: 350px;margin-right: 20px" alt="饿了么">
102+
<img src="https://x-file-storage.xuyanwu.cn/assets/mt.jpeg" style="height: 350px" alt="美团外卖">
103+
104+
或者点击以下链接,将页面拉到最下方点击“捐赠”即可
105+
106+
[Gitee上捐赠](https://gitee.com/dromara/x-file-storage)
107+
108+
-------
109+
110+
# 🌶️VIP交流群
111+
112+
扫描上方二维码捐赠 99 元,截图发我 `QQ1171736840` 即可加入 VIP 交流群(超过一年则需要再次捐赠,否则将进行清退)
113+
114+
也可以点击添加免费交流群
115+
<a target="_blank" href='https://jq.qq.com/?_wv=1027&k=eGfeNqka'>
116+
<img src='https://img.shields.io/badge/QQ%E7%BE%A4-515706495-orange' alt='515706495' />
117+
</a> 一起交流
118+
119+
-------
120+
89121
# 🏗️添砖加瓦
90122

91123
## 🎋分支说明
@@ -134,36 +166,10 @@ X File Storage 感谢各位小伙伴的信任与支持,如果您已经在项
134166
[在 Gitee 上登记](https://gitee.com/dromara/x-file-storage/issues/I83Q6R)<br/>
135167
[在 GitHub 上登记](https://github.com/dromara/x-file-storage/issues/114)
136168

137-
[tg.md](https://x-file-storage.xuyanwu.cn/assets/link/member-project.md ':include')
138-
139169
-------
140170

141171
# 🌏知识星球
142172

143173
<img src="https://x-file-storage.xuyanwu.cn/assets/zsxq.png" height="200px" alt="知识星球">
144174

145-
-------
146-
147-
# 💳捐赠
148-
如果你觉得这个项目不错,可以点个 Star 或捐赠请作者吃包辣条~,不想打赏的话用支付宝扫最后一个码可以领取个红包,在此表示感谢^_^
149-
150-
<img src="https://x-file-storage.xuyanwu.cn/assets/wx.png" style="height: 350px;margin-right: 20px" alt="微信">
151-
<img src="https://x-file-storage.xuyanwu.cn/assets/zfb.jpg" style="height: 350px;margin-right: 20px" alt="支付宝">
152-
<img src="https://x-file-storage.xuyanwu.cn/assets/zfb2.jpg" style="height: 350px;margin-right: 20px" alt="支付宝2">
153-
<img src="https://x-file-storage.xuyanwu.cn/assets/elm.jpg" style="height: 350px;margin-right: 20px" alt="饿了么">
154-
<img src="https://x-file-storage.xuyanwu.cn/assets/mt.jpeg" style="height: 350px" alt="美团外卖">
155-
156-
或者点击以下链接,将页面拉到最下方点击“捐赠”即可
157-
158-
[Gitee上捐赠](https://gitee.com/dromara/x-file-storage)
159-
160-
-------
161-
162-
# 🌶️VIP交流群
163-
164-
扫描上方二维码捐赠 99 元,截图发我 `QQ1171736840` 即可加入 VIP 交流群(超过一年则需要再次捐赠,否则将进行清退)
165-
166-
也可以点击添加免费交流群
167-
<a target="_blank" href='https://jq.qq.com/?_wv=1027&k=eGfeNqka'>
168-
<img src='https://img.shields.io/badge/QQ%E7%BE%A4-515706495-orange' alt='515706495' />
169-
</a> 一起交流
175+
[member-project.md](https://x-file-storage.xuyanwu.cn/assets/link/member-project.md ':include')

docs/_navbar.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
* 🌟文档版本 2.1.0
1+
* 🌟文档版本 2.2.0
22

3+
* [2.2.0](https://x-file-storage.xuyanwu.cn/2.2.0/)
34
* [2.1.0](https://x-file-storage.xuyanwu.cn/2.1.0/)
45
* [2.0.0](https://x-file-storage.xuyanwu.cn/2.0.0/)
56
* [1.0.3](https://x-file-storage.xuyanwu.cn/1.0.3/)

docs/_sidebar.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
* [📚简介](/ "简介")
22
* [🍭快速入门](快速入门 "快速入门")
33
* [🍬基础功能](基础功能 "基础功能")
4+
* [🚚迁移文件](迁移文件 "迁移文件")
45
* [🍉ACL 访问控制列表](acl "ACL 访问控制列表")
5-
* [🥑预签名 URL](预签名URL "签名 URL")
6+
* [🥑预签名 URL](预签名URL "预签名 URL")
67
* [🌼Metadata 元数据](Metadata "Metadata 元数据")
78
* [🥦存储平台](存储平台 "存储平台")
89
* [🌽文件适配器](文件适配器 "文件适配器")
910
* [🔍️识别文件的 MIME 类型](识别文件的MIME类型 "识别文件的 MIME 类型")
1011
* [🍵️计算哈希](hash "hash")
1112
* [🧪切面](切面 "切面")
1213
* [🌱脱离 SpringBoot 单独使用](脱离SpringBoot单独使用 "脱离 SpringBoot 单独使用")
14+
* [🍩在 Solon 中使用](在Solon中使用 "在 Solon 中使用")
1315
* [🙋‍♂️常见问题](常见问题 "常见问题")
1416
* [📜更新记录](更新记录 "更新记录")

docs/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
1111
<link rel="icon" href="https://x-file-storage.xuyanwu.cn//assets/logo4.png" type="image/x-icon"/>
1212
<link rel="stylesheet" href="https://x-file-storage.xuyanwu.cn/assets/docsify-theme-vue.css">
13+
<link rel="stylesheet" href="https://x-file-storage.xuyanwu.cn/assets/nav.css">
1314
<style>
1415
#main {
1516
max-width: 90%;

docs/在Solon中使用.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# 在 Solon 中使用
2+
3+
> Solon 官网 https://solon.noear.org/
4+
5+
`2.2.0` 版本开始原生支持在 `Solon` 中使用,之前的版本可以参考 [脱离 SpringBoot 单独使用](脱离SpringBoot单独使用)
6+
7+
先引入本项目, 注意这里是 `x-file-storage-solon`,而不是 `x-file-storage-core`,之后再参考 [快速入门](快速入门) 引入对应平台的依赖
8+
9+
```xml
10+
<dependency>
11+
<groupId>org.dromara.x-file-storage</groupId>
12+
<artifactId>x-file-storage-solon</artifactId>
13+
<version>2.2.0</version>
14+
</dependency>
15+
```
16+
17+
如果使用本地存储, 请务必添加 `solon.web.staticfiles` 依赖
18+
```xml
19+
<dependency>
20+
<groupId>org.noear</groupId>
21+
<artifactId>solon.web.staticfiles</artifactId>
22+
<version>2.7.1</version><!-- 当前行可去掉, 跟随 solon 的版本管理 -->
23+
</dependency>
24+
```
25+
26+
27+
默认情况下,Solon 会自动装配 `SolonFileStorageProperties` , 文件配置完全等同于使用 Spring 的情况, 可以在 `app.yml` 中按照 Spring 配置文件的格式进行配置。
28+
如:
29+
```yaml
30+
dromara:
31+
x-file-storage: #文件存储配置
32+
default-platform: minio-user #默认使用的存储平台
33+
thumbnail-suffix: ".min.jpg" #缩略图后缀,例如【.min.jpg】【.png】
34+
enable-multipart-file-wrapper: true #是否启用多文件包装器
35+
local-plus:
36+
- platform: local-plus-1 # 存储平台标识
37+
enable-storage: true #启用存储
38+
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
39+
domain: http://127.0.0.1:8080/file/ # 访问域名,例如:“http://127.0.0.1:8030/file/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
40+
base-path: local-plus/ # 基础路径
41+
path-patterns: /file/ # 访问路径
42+
storage-path: D:/temp/ # 存储路径
43+
minio:
44+
- platform: minio-user # 存储平台标识
45+
enable-storage: true # 启用存储
46+
access-key: j9rMyECcmNH0lNBqPfOo
47+
secret-key: 0NYFJSl4D8msuxHirenthXA4lvju4c3QNdmQ29Ob
48+
end-point: http://127.0.0.1:9000
49+
bucket-name: user
50+
# domain: ?? # 访问域名,注意“/”结尾,例如:http://minio.abc.com/abc/
51+
base-path: user/ # 基础路径
52+
- platform: minio-dept # 存储平台标识
53+
enable-storage: true # 启用存储
54+
access-key: j9rMyECcmNH0lNBqPfOo
55+
secret-key: 0NYFJSl4D8msuxHirenthXA4lvju4c3QNdmQ29Ob
56+
end-point: http://127.0.0.1:9000
57+
bucket-name: dept
58+
# domain: ?? # 访问域名,注意“/”结尾,例如:http://minio.abc.com/abc/
59+
base-path: dept/ # 基础路径
60+
```
61+
62+
同时, 由于 Solon 和 Spring 环境不一致, 部分功能使用会有差异, 详情参见 [Solon 与 Spring Boot 的区别](https://solon.noear.org/article/compare-springboot)
63+
64+
在注入 `fileStorageService` 后, 可以使用 `fileStorageService` 进行文件操作, 例如上传、下载、删除等。完全等同 Spring 的使用方式。
65+
66+

docs/基础功能.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
### 基本的上传方式
66

7-
`of`方法支持 File、MultipartFile、byte[]、InputStream、URL、URI、String、HttpServletRequest,大文件会自动分片上传。如果想支持更多方式,请阅读 [文件适配器](文件适配器) 章节
7+
`of`方法支持 File、MultipartFile、UploadedFile、byte[]、InputStream、URL、URI、String、HttpServletRequest,大文件会自动分片上传。如果想支持更多方式,请阅读 [文件适配器](文件适配器) 章节
88

99
```java
1010
// 直接上传
@@ -223,6 +223,10 @@ fileStorageService.abortMultipartUpload(fileInfo).abort();
223223
> 2. 建议将 FileInfo 保存到数据库中,这样就可以使用 `fileStorageService.getFileInfoByUrl("https://abc.def.com/xxx.png")` 来获取 FileInfo 方便操作,详情请阅读 [保存上传记录](基础功能?id=保存上传记录) 章节
224224
> 3. 手动分片上传暂时无法生成缩略图,将在后续版本提供追加缩略图功能。
225225
226+
### 客户端上传
227+
228+
通过预签名 URL 的方式可以实现客户端上传,详情查看 [预签名 URL 上传](预签名URL?id=上传)
229+
226230

227231
### 监听上传进度
228232

@@ -526,6 +530,64 @@ CREATE TABLE `file_part_detail`
526530

527531
<!-- fold:end -->
528532

533+
## 获取文件
534+
535+
```java
536+
//通过 FileInfo 获取文件信息
537+
RemoteFileInfo info = fileStorageService.getFile(fileInfo);
538+
//通过 FileInfo 获取缩略图文件信息
539+
RemoteFileInfo info2 = fileStorageService.getThFile(fileInfo);
540+
541+
//将结果转成 FileInfo 方便进行其它操作
542+
FileInfo fileInfo2 = info.toFileInfo();
543+
//将缩略图文件信息也 set 到 FileInfo 中
544+
info2.toFileInfoTh(fileInfo2);
545+
546+
//自行传入 path 及 filename 获取文件信息
547+
RemoteFileInfo info3 = fileStorageService.getFile().setPath("test/").setFilename("123.jpg").getFile();
548+
Assert.notNull(info3, "文件不存在");
549+
log.info("获取文件结果:{}", info3);
550+
//文件元数据
551+
MapProxy metadata = info3.getKebabCaseInsensitiveMetadata();
552+
//文件用户元数据
553+
MapProxy userMetadata = info3.getKebabCaseInsensitiveUserMetadata();
554+
555+
//获取原始文件信息,这里以阿里云为例
556+
OSSObject ossObject = info3.getOriginalAliyunOssObject();
557+
```
558+
559+
> [!WARNING|label:重要提示:]
560+
> 将 RemoteFileInfo 转为 FileInfo 时,有以下几点需要注意:
561+
> 1. 一般情况下 FileInfo 中的 createTime(创建时间)就是 RemoteFileInfo 中的 lastModified(最后修改时间),如果有误,可以自行设置
562+
> 2. RemoteFileInfo 中的 metadata 元数据值为 Object 类型,FileInfo 中的元数据值为 String 类型,目前是将 Object 类型使用 toString() 方法转为 String 类型,应该可以满足大部分情况,如有需要可以自行转换
563+
564+
## 列举文件
565+
566+
```java
567+
//是否支持列举文件
568+
ListFilesSupportInfo isSupportListFiles = fileStorageService.isSupportListFiles();
569+
570+
//列举文件及目录
571+
ListFilesResult result = fileStorageService.listFiles().setPath("test/").listFiles();
572+
result.getDirList().forEach(info -> log.info("目录:{}", info));
573+
log.info("列举目录完成,共 {} 个目录", result.getDirList().size());
574+
result.getFileList().forEach(info -> log.info("文件:{}", info));
575+
log.info("列举文件完成,共 {} 个文件", result.getFileList().size());
576+
log.info("列举文件全部结果:{}", result);
577+
578+
//列表是否被截断,就是当前目录下还有其它文件或目录超出最大数量未被列举
579+
log.info("列表是否被截断:{}", result.getIsTruncated());
580+
log.info("下次列举的起始位置:{}", result.getNextMarker());
581+
582+
//其它更多参数
583+
ListFilesResult result2 = fileStorageService.listFiles()
584+
.setPath("test/") // 指定目录
585+
.setMaxFiles(10) //要列举的最大文件及目录数量
586+
.setFilenamePrefix("abc") // 文件名前缀
587+
.setMarker("123456") //列举的起始位置,从上一次列举结果中获取
588+
.listFiles();
589+
```
590+
529591
## 下载
530592

531593
### 多种下载方式

0 commit comments

Comments
 (0)