文件存储目录设计 & 文件资源地址URI的设计

1. 前言

文件为什么要做目录管理?文件资源地址又该如何设计定义?

设计的由来都是基于特定需求,一般我们会对文件有什么需求呢?

  1. 区分文件上传来源/用途/场景;
  2. 文件命名的唯一性;
  3. 对文件进行处理,例如图像文件缩略图、视频抽封面等;
  4. 文件加密需求,例如用户聊天文件、账单等;
  5. 文件删除,例如删除特定场景下的文件、删除一年之前的文件;
  6. 文件迁移、备份;

本文不讨论文件存储系统本身的设计, 仅是从单纯的文件存储需求而言来设计文件存储目录及文件名。

2. 业界调研

2.1 业界各大厂文件命名

百度

  • 示例地址:

    • 头像: httpshttps://himg.bdimg.com/sys/portrait/item/public.1.4dc633e9.yzF6Dpkmm4OwSTNiS4Iz6A.jpg
    • 新闻文章中的图片:https://pics7.baidu.com/feed/962bd40735fae6cd7780e4d647231a2a43a70fea.jpeg@f_auto?token=94c67b39c02821fe985683e57b868f61
    • [百度图片]模块中的图片:https://t7.baidu.com/it/u=1785207335,3397162108&fm=193&f=GIF
    • 百度视频封面:https://f7.baidu.com/it/u=1718481929,608659536&fm=222&app=106&f=JPEG?x-bce-process=image/quality,q_80/resize,m_fill,w_660,h_370/format,f_auto
    • 百度视频:https://vdept3.bdstatic.com/mda-qeva57sjwpnzbd42/sc/h264/1717053003030242811/mda-qeva57sjwpnzbd42.mp4?v_from_s=hkapp-haokan-hbe&auth_key=1717093758-0-0-2f72b8b205d4c609a48d6e5044f7513c&bcevod_channel=searchbox_feed&cr=2&cd=0&pd=1&pt=3&logid=1758430182&vid=14518258860174020884&klogid=1758430182&abtest=101830_1-102148_1-17451_1
  • 分析:

    • 头像中有疑似有用户信息;
    • 新闻图片使用了guid;
    • 且还使用了token用于鉴权;
    • 百度视频封面x-bce-process用了定义的图片处理样式,视频地址增加了auth_key鉴权相关;
    • 视频地址中1717053003030242811是时间按信息;

阿里-淘宝

  • 示例地址:

    • 头像: https://wwc.alicdn.com/avatar/getAvatar.do?userNick=快乐悲魂&width=60&height=60&type=sns&_input_charset=UTF-8
    • 商品图片:https://gw.alicdn.com/imgextra/i2/2200632862640/O1CN011Tv5H61VNAWxjYAWQ_!!2200632862640.jpg_Q75.jpg_.webp
    • 商品详情:https://img.alicdn.com/imgextra/i4/2200632862640/O1CN01Ia8wGf1VNAZYZPAC1_!!2200632862640.jpg
    • 商品图片2: https://img.alicdn.com/imgextra/i3/299218127/O1CN01KmSEWV29uDerhttbW_!!299218127.jpg_80x80.jpg
  • 分析:

    • 头像地址携带了用户信息;
    • 商品图片疑似携带店铺信息和base64编码命名;

腾讯

  • 示例地址:

    • 图1:https://inews.gtimg.com/om_bt/Oj7iqkdFIvOFaugI6oIwpdPgxCQ7w7f4hmIcDGVJd85DcAA/641
    • 图2:https://inews.gtimg.com/news_ls/OtPMgQTuFo3LApiZ9FAfkiuSfpJTBi5_07NylI54flipQAA_870492/0
    • 游戏图片:https://gamer.qpic.cn/2024/05/23_fad7ede093ef5a6db810c72785ebc418.jpg?imageMogr2/crop/564x320/format/webp
  • 分析:

    • 区分了域名;
    • 区分了目录;
    • 游戏图片携带了日期+guid;
    • imageMogr2使用了自定义样式;

美团

  • 示例地址:

    • 图1:https://img.meituan.net/smartvenus/53b881ae4ff6ed7eb344d2479a611bff283561.jpg@1334w_60Q%7Cpr=1
    • 图2:https://img.meituan.net/smartvenus/a35d5aa65704808cfc6a614f21e918bd258524.jpg@620w_60Q%7Cpr=1.webp
    • 美团技术文章中图片:https://p1.meituan.net/travelcube/2d405d5c0aee2c1a3d0ac2a4caae2106427033.png
  • 分析:

    • 区分不同域名;
    • 使用guid命名;
    • 使用@符作为样式分割符来处理不同的样式文件;

抖音

  • 示例地址:

    • 图1:https://p3-pc-sign.douyinpic.com/tos-cn-p-0015/ocgDFBtyuAoDpd6WEBC8EfejN7V9mIAghA59gl~tplv-dy-resize-origshort-autoq-75:330.jpeg?biz_tag=pcweb_cover&from=3213915784&s=PackSourceEnum_DOUYIN_WEB_NEW_PAGE&sc=cover&se=false&x-expires=2032441200&x-signature=8vZhTHbvIyEu5WepMlIuuB4CjCU%3D
    • 图2:https://p3-pc-weboff.byteimg.com/tos-cn-i-9r5gewecjs/a795fb49bcbcf8cb1c762a69d57aee48.png
    • 视频地址:https://v3-webc.douyinvod.com/afeba8447b334b078ce777a5ce3d359f/6658bbe6/video/tos/cn/tos-cn-ve-15c001-alinc2/oMQfTMeB2CkjuA7qUTIABLIBlJGFupL00eYhYE/
  • 分析:

    • 区分不用域名;
    • 区分目录;
    • 使用了guid;

CSDN

  • 示例地址:

    • 头像地址:https://profile-avatar.csdnimg.cn/43dddb50b85448eeb2a4089eb2210d0a_kuailebeihun.jpg
    • 不模块的博文文章中图片的地址
      • https://img-blog.csdnimg.cn/direct/0357972c4ea7489a80e5032732424ab4.png
      • https://img-community.csdnimg.cn/images/21894b3380844b22a4755cde7fe98b59.png
    • 图片带水印地址:https://img-blog.csdnimg.cn/20190929112628623.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3V5b25nZ28=,size_16,color_FFFFFF,t_70
  • 分析:

    • 不同场景或许使用了不同的bucket
    • 有区分使用不同目录;
    • 文件都使用uuid命名;
    • x-oss-process很容易看出来用的是阿里的对象存储;

2.2 对象存储

一般来说,现在厂商提供的对象存储服务远比自己搭建的文件系统要稳定、成本更低。了解对象存储的功能、哪怕就算自建文件系统,有利于了解对象存储的需求,和应对文件目录名称的命名。

在对象存储中,目录名称+文件名称,整体都作定义为对象的文件名;目录层级也是文件名的一部分。

2.2.1 功能说明

阿里OSS、七牛kodo、腾讯cos、火山tos等各大厂商的对象存储功能类似;

本文以OSS为例说明,列举几个和文件地址命名相关的几点功能:

  • bucket区分私有公有
  • 图片处理可以通过参数自定义样式;
  • 可以按照分隔符自定义样式,样式图片可以通过图片访问链接 + 分隔符 + 样式名称进行访问;
  • 生命周期(低频/归档/删除)、跨区域复制、导出文件清单列表、镜像回源 可以按照文件名前缀设定配置;
  • 镜像回源还可以处理文件名后缀设置;

2.2.2 OSS命名建议

以下3点是官网文档原话:

  1. 使用有意义的名称。Object的名称应该反映对象的内容和用途,方便查找和理解。例如,使用文件名、日期、用户ID等信息作为Object的名称。
  2. 使用唯一的名称。Object的名称应该是全局唯一的,以避免命名冲突。可以在Object的名称中包含一些随机数或UUID等信息,确保名称的唯一性。
  3. 使用前缀来组织数据。前缀是Object的名称的一部分,可以用于为Object创建层次结构。例如,按日期、用户ID、地域等信息作为前缀,可以更好地组织和管理数据。

其中,在文件名中使用用户ID等私密信息数据,个人不太建议;特别是地址中仅有这类信息时,容易造成数据泄露。
就算真的使用,也建议使用加密算法、最次base64一下。

3. 文件目录设计

${catalog}/${day}/${guid:0:4}/${guid}${flag}.${fileType}

  • catalog 目录,数字和小写字母组成;可以根据自己需要限制一下长度
    • 用于区分场景、上传来源
    • 也可以区分私有、公有(三方对象存储可以新建不同bucket)
    • 使用场景:原始文件可以衍生更多的文件可以使用flag标识,例如MP4视频可以处理成h265/h264/flv等格式,可以使用不同的目录
  • day 日期,例如:20240531
    • 可以根据文件地址中的日期,快速查找文件上传、处理的日志文件
    • 可以按照一定前缀处理文件,例如按照时间前缀导出文件清单
    • 文件本地落盘方便处理
  • guid 全局唯一标识符,完整是36位
    • 取前4位作为三级目录,本地落盘文件会分散各个文件夹;(这个在uri上非必要,可以在落盘时逻辑上新建出这个目录)
    • guid作为文件名的一部分
    • 用于作为文件的唯一标识
  • flag 特征符,非必须,统一使用_作为flag的前缀
    • 一些特殊定义的信息,例如用户ID、版本、用途标识等
  • fileType 点后面跟文件的后缀类型,例如:jpg/JPEG/mp4/tar.gz

需满足正则^[a-z0-9]{2,16}\/[0-9]{8}\/[a-z0-9]{4}\/[a-z0-9-]{36}(_\w+)?\.[.\w]+$

以Python为例,代码生成对象名称uri:

import uuid
import datetime

catalog = "test"
guid = str(uuid.uuid4())
day = datetime.datetime.now().strftime("%Y%m%d")
flag = "_ori"
fileType = "jpg"

uri = f"{catalog}/{day}/{guid[:4]}/{guid}{flag}.{fileType}"
print(uri)
# test/20240531/bedc/bedcb587-0334-47ba-8af5-4a40e49c9f27_ori.jpg

4. 其他建议

  • 文件命名规则不要交由client端,容易被攻击;
    • 对外的接口只传递文件内容和场景即可,文件地址由后端生成;
  • 若是使用三方对象存储例如OSS,建议屏蔽样式自定义参数,采用后台配置样式的方式;
  • 不太建议将用户信息放在文件名称上,容易造成数据泄露;
  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值