8.9 gfs 对象存储¶
8.9.1 快速开始¶
登录¶
访问 https://gfs.ihep.ac.cn/,使用高能所统一认证账号登录。
在网页上获取 Access Key 和 Secret Key。

Linux 客户端挂载¶
-
安装 jcli 客户端
选择对应 CPU 架构的 jcli 客户端下载链接:
- amd64:
https://file-ocloud.ihep.ac.cn/jcli/amd64/jcli - arm64:
https://file-ocloud.ihep.ac.cn/jcli/arm64/jcli
例如:在 Linux 环境下,使用 wget 或 curl 下载 jcli 客户端工具包。
配置至用户的 HOME 目录的 bin 下,确保可直接在命令行使用 jcli 命令操作。
- amd64:
-
配置认证信息
- 输入 Access Key 和 Secret Key
- 输入网关地址(访问端点)
https://fgws3-gfs.ihep.ac.cn - 代理可不选
- 存储桶可上下键选择或手动输入桶名
交互过程示例:
-
查看存储桶详细信息
若能输出无报错,则配置正确,可进行后续操作。
-
挂载
例如:
mkdir /scratchfs2/cc/username/gfs_bucket # 创建挂载点 jcli mount -f /scratchfs2/cc/username/gfs_bucket/ --daemon # 执行挂载,提示"调用子进程运行服务..." ls /scratchfs2/cc/username/gfs_bucket/ # 验证挂载是否成功,若能看到目录下文件,则表明挂载成功 # 输出示例:'Jwanfs 用户手册【简易版】.pdf' mydir tmp 演示目录 df -h # 查看挂载状态 # 输出示例:20005-ihep-imel-120624 512G 3.0M 512G 1% /scratchfs2/cc/username/gfs_bucket随后可像访问本地目录一样访问该存储桶内的文件。
Windows 客户端挂载¶
-
下载链接:
-
配置环境变量,将 jcli.exe 所在的目录添加到环境变量中。
- 找到 jcli 文件的位置。
- 右键点击电脑屏幕左下角的 Windows 图标,选择"系统"。
- 在系统窗口左侧,点击"高级系统设置"。
- 在系统属性窗口中,点击"环境变量"按钮。
- 在环境变量窗口中,找到"系统变量"下的"Path"变量,然后点击"编辑"。
- 在编辑环境变量窗口中,点击"新建",然后输入 jcli 文件所在的目录路径。
- 点击"确定"保存更改。
-
下载软件 WinFSP:点击此处下载。下载好后,双击安装 WinFSP。
-
配置认证信息:Win+R 输入
cmd,调出命令行窗口,输入jcli auth进行配置 AK、SK、服务端点(同 Linux 端)。配置好后,在命令行窗口输入jcli mount -f Z: --daemon进行挂载。
8.9.2 网页端访问¶
请使用高能所统一认证账号申请权限并登录系统。账户开通后,将自动为您提供 1TB 的默认存储空间。

桶管理¶
系统提供包括创建、删除、扩容、回收站等功能。

文件管理¶
单击桶名进入文件管理界面。
桶内文件遵循网盘级的用户操作逻辑与数据管理模式,提供如下功能:
- 发布资源
- 上传文件
- 下载文件
- 创建目录
- 预览文件:在文件列表页面点击 ...,在菜单中点击 预览 可以直接预览文件,预览文件时文件无需下载至本地
- 删除文件(回收站中文件默认保存 30 天)
- 分享文件(可选分享时长、设置分享密码)

文件上传下载¶
在文件列表页面点击上传文件会进入上传文件流程。
上传文件弹窗中可以添加更多文件或确认上传。

右键选中文件,单击下载即可。
文件分享¶
点击文件分享生成共享链接与访问密码:

分享的文件在分享列表可以查看,复制分享信息。

注意
- 可自定义分享期限和访问密码
- 只能分享文件,无法分享目录
- 所分享的目标被删除后分享链接仍然有效,但无法下载文件
预览文件¶
在文件列表页面点击 ...,在菜单中点击 预览 可以直接预览文件。 是否可以使用预览功能与文件类型有关,支持文件类型:
-
图片:jpg、png 等
-
视频:mp4、avi 等
-
文档:pdf、docx 等
-
音频:mp3、wav 等
-
文本:txt、md 等
-
高能物理数据文件:root、h5
资源发布¶
用户可将 文件/目录 发布至资源广场,供平台其他用户下载。
初次发布资源需要先在 我的店铺 页添加一个店铺,填写名称、概述、分类及标签后完成创建。

在文件列表页面点击 ...,在菜单中点击 发布资源 会进入发布资源流程。
输入资源信息即可将对应文件或目录发布至资源广场提供用户下载。
在 我的店铺 页可查看已发布资源,获取下载链接,也可在资源广场看到该店铺及资源。

密钥管理(重要)¶
密钥(AK 和 SK)是系统识别用户的 唯一凭证,使用密钥访问网关的操作代表密钥所属人的操作,请妥善保管自己的认证信息。
资源广场¶
用户发布的资源可以从这里获取详细信息,并下载。
如果您想快速找到特定的资源,可以使用搜索功能。在资源广场页面的搜索框中输入您想要查找的资源的关键字。

个人设置¶
可修改昵称、邮箱等。
8.9.3 官方客户端¶
JWanFS 提供官方客户端 jcli,推荐直接使用官方客户端访问。此外 JWanFS 还支持通用的 S3 接口,可直接使用 S3 客户端访问平台资源。
软件下载¶
下载链接:
| CPU 架构 / 操作系统 | Windows | MacOS | Linux |
|---|---|---|---|
| Intel/AMD 64bit(amd64/x86) | 下载 | 下载 | 下载 |
| ARM/Apple-Silicon(arm64/aarch64) | 下载 | 下载 | 下载 |
配置环境变量¶
-
Linux
-
Windows
在 Windows 系统中,点击下载链接下载客户端可执行文件,将 jcli 添加到环境变量中以便于全局使用,可以按照以下步骤操作:
- 找到 jcli 文件的位置。
- 右键点击电脑屏幕左下角的 Windows 图标,选择"系统"。
- 在系统窗口左侧,点击"高级系统设置"。
- 在系统属性窗口中,点击"环境变量"按钮。
- 在环境变量窗口中,找到"系统变量"下的"Path"变量,然后点击"编辑"。
- 在编辑环境变量窗口中,点击"新建",然后输入 jcli 文件所在的目录路径。
- 点击"确定"保存更改。
填写认证信息¶
手动输入配置¶
复制网页上获得的 AK、SK 以及文件网关,配置客户端并选择对应的存储桶。
网页获取密钥示意图:

网页获取网关信息示意图:

也可在密钥管理页面点击 接入指南 查看可使用网关节点。

jcli 配置认证信息命令:
其中,-
AccessKey/SecretKey:输入从网页端获取的密钥。
-
服务端点:输入你选择的网页上的网关,例如
https://fgws3-gfs.ihep.ac.cn -
Bucket 选择:按提示选择默认存储桶。
注意
通过 jcli auth 可生成 aksk 对应的认证文件,后续 jcli 将通过该认证文件访问 gfs 存储。
也可以通过 jcli auth -e 重置配置,重新填写认证信息。
生成 jcli token 配置¶
在密钥管理页点击 生成 JCLI Token。

在展开的选项卡中依次选择桶和网关,复制生成的 token 或命令,在安装好了 jcli 的控制台粘贴,即可快速完成 jcli 认证的配置。

配置文件说明¶
jcli 支持指定配置文件的位置,默认位置为 ~/.jcli/token/auth。
创建完成后,用这个认证文件操作时,只需要加上 -auth=/你的路径/认证文件名 就可以了。
例如:
如果想把它设为默认认证文件,后面再加个 -default:
挂载作为虚拟磁盘¶
-
Linux
-
确保已经安装 FUSE,一般系统已经内置,如果未安装可参考如下命令进行安装:
CentOS/openEuler 等使用 rpm 包的系统运行如下命令进行安装:
Ubuntu/Debian 等使用 deb 包的系统运行如下命令进行安装: - 确保已经配置好jcli auth:执行查看目录命令jcli ls,若正确输出目录下文件无报错,则配置正确。 -
挂载作为共享目录
- 挂载后配置权限 例1:修改 /tmp/host 文件权限为 0644(rw-r--r--) 例2:修改 /tmp/host 文件所有者为 root
-
挂载时指定访问权限
参数说明:jcli mount /lact \ -bucket 20001-lact \ -mode-mnt "0770" \ -mode-mnt-uid 0 \ -mode-mnt-gid 1000 \ -mode-uid 0 \ -mode-gid 1000 \ --daemon-
-mode-mnt "0770":仅允许所有者(root)和所属组(lact)读写。 -
-mode-*-gid 1000:强制文件归属为 GID 1000 的组。
-
-
-
Windows
- 下载软件 WinFSP:点击此处下载
- 确保已经配置好
jcli auth -
执行挂载命令
- 即可像使用本地磁盘一样使用 JWanFS 统一存储空间jcli mount {盘符},Windows 的盘符必须从大写的 A-Z 中选取。
-
MacOS
Mac 挂载需要安装 MacFUSE,点击下载安装。
-
挂载路径示例
若使用 jcli mount Z: 挂载到"我的电脑",或使用 jcli mount /home/lhaaso/testuser/gfs 挂载到 Linux 服务器,则路径映射关系如下表所示。
| 桶内路径 | Windows | Linux |
|---|---|---|
| Image.jpg | Z:\Image.jpg | /home/lhaaso/testuser/gfs/Image.jpg |
卸载¶
手动卸载会强制将目录内容写回磁盘,保障数据安全。
交互模式¶
直接执行 jcli 将进入交互界面,支持常见命令如 ls、cd、put、get 等,使用方式与 Linux Shell 类似。
jcli put等子命令可实现一次性文件上传,jcli mount提供持续挂载的方式用于长时间读写。jcli help可查看详细命令说明。
全局参数:
--help 参数值类型:bool
打印帮助信息
-ak 参数值类型:string
AccessKey
-auth 参数值类型:string
认证文件路径
-bucket 参数值类型:string
默认存储桶
-endpoint 参数值类型:string
服务端点地址
-sk 参数值类型:string
SecretKey
子命令列表:
命令 别名 作用
auth 认证服务
cat 查看文件内容
chmod 修改对象权限
chown 修改对象权限
config 配置认证信息
cp copy 复制对象
cron crontab,task 定时任务管理
rm delete,del 删除文件
du size 计算文件或目录大小
etag 计算文件ETag
expire 获取AKSK过期时间
file-server 启动文件服务器
ftp 启动FTP服务端提供局域网用户访问
get pull,download 下载文件
head 查看文件首部内容
list ls,ll 查看文件列表
md5sum md5 计算文件MD5
mkdir 创建目录
mount 挂载存储桶
mv move,rename 移动或重命名远端文件
put push,upload 上传文件
quota 获取文件信息
stat stats,info 获取文件信息
symlink 修改对象权限
sync 同步对象
tail 查看文件尾部内容
token 创建临时AKSK
update 更新客户端版本
客户端升级¶
若需要使用新功能,可通过如下命令更新 jcli 客户端。
8.9.4 第三方兼容客户端¶
NetMount¶
NetMount 是一个简单、易用、高效的开源云存储管理工具。它可以将云存储整合为本地文件系统,使用户能无缝访问云端资源,通过虚拟文件系统技术实现高效操作,简化数据管理,提供流畅的云-本地交互体验。
打开 NetMount 点击 管理,点击 添加 进入添加流程,选择 对象存储 进入下一步。

填写桶信息以添加 JWanFS 存储桶。

其中, 存储名称 为在 NetMount 中的名称,可自定义。
桶 为 JWanFS 的存储桶,Endpoint 为文件网关 S3 网关地址。
Access Key ID 与 Secret Access Key 填写 OSCA 的认证 AK 与 SK。
注意事项
启用 force_path_style,选择 List Object Version 为 V2 后保存。
云卷(Cloud Volume)¶
云卷(Cloud Volume)是一款面向 macOS、Windows、Linux 的 Flutter 桌面客户端,可以一站式管理 S3 兼容对象存储、WebDAV 与百度网盘。它不只是一个"桶列表 + 上传下载"工具,还内置本地缓存、可挂载 WebDAV 视图、应用级回收站、分享链接管理与任务队列,更贴近桌面文件管理器的工作流。
云卷项目仓库与发行包:
项目主页:https://github.com/lfhy/cloud-volume
GitHub Release(macOS / Windows / Linux 桌面版 + CLI):在仓库 Releases 页下载最新版本。
8.9.5 SDK¶
gfs 对象存储兼容 S3 协议,可使用各语言的 AWS S3 SDK 访问。程序接入时通常只需要配置四项信息:
Endpoint:gfs S3 网关地址,例如https://fgws3-gfs.ihep.ac.cnAccessKeyId/AccessKeySecret:访问密钥Region:可使用us-east-1- Path-Style:必须开启路径模式,避免 SDK 将桶名解析成子域名
安装 SDK¶
初始化客户端¶
以下示例中的 AccessKeyId、AccessKeySecret、your-bucket-name 请替换为实际信息。
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
func newS3Client() *s3.S3 {
conf := &aws.Config{
Region: aws.String("us-east-1"),
Endpoint: aws.String("https://fgws3-gfs.ihep.ac.cn"),
Credentials: credentials.NewStaticCredentials("AccessKeyId", "AccessKeySecret", ""),
S3ForcePathStyle: aws.Bool(true),
DisableSSL: aws.Bool(false),
}
sess := session.Must(session.NewSession(conf))
return s3.New(sess)
}
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;
import java.net.URI;
public class S3ClientFactory {
public static S3Client create() {
return S3Client.builder()
.region(Region.US_EAST_1)
.endpointOverride(URI.create("https://fgws3-gfs.ihep.ac.cn"))
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create("AccessKeyId", "AccessKeySecret")))
.serviceConfiguration(S3Configuration.builder()
.pathStyleAccessEnabled(true)
.build())
.build();
}
}
基本操作¶
下面示例演示上传、列举、下载和删除一个对象。对象 Key 建议使用 目录/文件名 形式,例如 demo/hello.txt;拼接路径时不要让文件名以 / 开头,避免生成 //。
import (
"bytes"
"fmt"
"io"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func demo() {
svc := newS3Client()
bucket := "your-bucket-name"
key := "demo/hello.txt"
_, err := svc.PutObject(&s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Body: bytes.NewReader([]byte("hello gfs")),
})
if err != nil {
fmt.Println("上传失败:", err)
return
}
list, _ := svc.ListObjects(&s3.ListObjectsInput{Bucket: aws.String(bucket)})
for _, obj := range list.Contents {
fmt.Printf("%s %d\n", *obj.Key, *obj.Size)
}
obj, err := svc.GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
fmt.Println("下载失败:", err)
return
}
defer obj.Body.Close()
data, _ := io.ReadAll(obj.Body)
fmt.Println(string(data))
_, _ = svc.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
}
bucket = 'your-bucket-name'
key = 'demo/hello.txt'
s3_client.put_object(Bucket=bucket, Key=key, Body=b'hello gfs')
print('上传完成')
resp = s3_client.list_objects_v2(Bucket=bucket, Prefix='demo/')
for obj in resp.get('Contents', []):
print(obj['Key'], obj['Size'])
obj = s3_client.get_object(Bucket=bucket, Key=key)
print(obj['Body'].read().decode('utf-8'))
s3_client.delete_object(Bucket=bucket, Key=key)
print('删除完成')
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import java.nio.charset.StandardCharsets;
public class GfsDemo {
public static void main(String[] args) {
String bucket = "your-bucket-name";
String key = "demo/hello.txt";
try (S3Client s3 = S3ClientFactory.create()) {
s3.putObject(
PutObjectRequest.builder().bucket(bucket).key(key).build(),
RequestBody.fromString("hello gfs")
);
s3.listObjectsV2(ListObjectsV2Request.builder()
.bucket(bucket)
.prefix("demo/")
.build())
.contents()
.forEach(obj -> System.out.println(obj.key() + " " + obj.size()));
byte[] data = s3.getObjectAsBytes(GetObjectRequest.builder()
.bucket(bucket)
.key(key)
.build()).asByteArray();
System.out.println(new String(data, StandardCharsets.UTF_8));
s3.deleteObject(DeleteObjectRequest.builder()
.bucket(bucket)
.key(key)
.build());
}
}
}
const {
PutObjectCommand,
ListObjectsV2Command,
GetObjectCommand,
DeleteObjectCommand,
} = require('@aws-sdk/client-s3');
async function demo() {
const bucket = 'your-bucket-name';
const key = 'demo/hello.txt';
await s3Client.send(new PutObjectCommand({
Bucket: bucket,
Key: key,
Body: 'hello gfs',
}));
const list = await s3Client.send(new ListObjectsV2Command({
Bucket: bucket,
Prefix: 'demo/',
}));
for (const obj of (list.Contents || [])) {
console.log(obj.Key, obj.Size);
}
const file = await s3Client.send(new GetObjectCommand({
Bucket: bucket,
Key: key,
}));
console.log(await file.Body.transformToString());
await s3Client.send(new DeleteObjectCommand({
Bucket: bucket,
Key: key,
}));
}
demo().catch(console.error);
<?php
$bucket = 'your-bucket-name';
$key = 'demo/hello.txt';
$s3->putObject([
'Bucket' => $bucket,
'Key' => $key,
'Body' => 'hello gfs',
]);
echo "上传完成\n";
$list = $s3->listObjectsV2([
'Bucket' => $bucket,
'Prefix' => 'demo/',
]);
foreach ($list['Contents'] ?? [] as $obj) {
echo $obj['Key'] . ' ' . $obj['Size'] . "\n";
}
$file = $s3->getObject([
'Bucket' => $bucket,
'Key' => $key,
]);
echo $file['Body'] . "\n";
$s3->deleteObject([
'Bucket' => $bucket,
'Key' => $key,
]);
echo "删除完成\n";
使用提示¶
- AccessKeyId 和 AccessKeySecret 是访问凭证,请勿写入公开代码仓库。
- 单次列举默认只返回一部分对象;对象很多时需要按 SDK 提供的翻页参数继续查询。
- 大文件上传建议使用 SDK 的分块上传能力。
8.9.6 概念简介¶
gfs 是基于 JWanFS 构建的统一对象存储实例。系统实施了严格的用户级数据隔离机制,确保每位用户拥有独立、安全的专属存储空间。同时,gfs 打通了操作系统壁垒,支持 Windows、Linux、macOS 等多平台环境下的无缝访问,为用户提供类网盘式的轻量化、便捷化数据管理体验。
桶(Bucket)¶
功能类似你熟悉的文件系统根目录,是 JWanFS 里存储数据的顶层容器。 桶的名称全局唯一,创建后无法修改。 命名规则:只能包括小写字母、数字和短划线(-),必须以小写字母或者数字开头和结尾。
服务端点(文件网关 Endpoint)¶
用户访问数据的入口,格式为:IP+端口
gfs 目前提供一个负载均衡网关,可直接使用 https://fgws3-gfs.ihep.ac.cn。
访问密钥(AccessKey 与 SecretKey)¶
访问密钥(由 AccessKey 与 SecretKey 组成)是用户访问 JWanFS 存储服务的核心身份认证凭证,用于对访问请求进行权限校验,保障数据访问的安全性。用户可通过系统网页管理端获取该密钥信息。
附录¶
其他使用方式见客户端手册:jwanfs 手册。
常见问题(FAQ)¶
见常见问题。
有问题?输入后跳转到对话页继续交流