如何处理双层文件扩展名?生成不重复文件名的技术难题
解决文件名去重时的扩展名处理问题
要实现符合浏览器风格的文件名去重,核心是准确区分文件名主体和扩展名(含多层),把(1)这类后缀加在主体和扩展名之间。下面是具体的实现思路:
核心方案:基于已知多扩展名列表+后缀匹配
预设常见多扩展名集合
先整理出行业通用的多层扩展名(比如tar.gz、tar.bz2、tar.xz、zip.001、rar.part等),这些是需要整体保留的扩展名组合。拆分文件名并匹配扩展名
- 将文件名按
.分割成片段数组,比如example.tar.gz拆成['example', 'tar', 'gz'],product-v.1.0.0.zip拆成['product-v', '1', '0', '0', 'zip']。 - 从后往前检查片段组合是否在预设集合中:
- 如果数组长度≥3,先尝试拼接最后两个片段(比如
tar+gz=tar.gz),若匹配预设的多扩展名,则主体为前面所有片段用.连接,扩展名为这两个片段的组合; - 若不匹配多扩展名,则主体为最后一个片段之前的所有内容用
.连接,扩展名为最后一个片段; - 如果文件名没有扩展名(比如
readme),直接把整个文件名作为主体。
- 如果数组长度≥3,先尝试拼接最后两个片段(比如
- 将文件名按
生成去重文件名
在主体末尾添加(n)后缀(n从1开始递增,直到找到不存在的文件名),再拼接扩展名即可。
示例验证
- 双层扩展名:
example.tar.gz→ 主体example+ 后缀(1)+ 扩展名.tar.gz→example(1).tar.gz - 带点的文件名+单层扩展名:
product-v.1.0.0.zip→ 主体product-v.1.0.0+ 后缀(1)+ 扩展名.zip→product-v.1.0.0(1).zip - 普通带点文件名:
file.name.txt→ 主体file.name+ 后缀(1)+ 扩展名.txt→file.name(1).txt - 无扩展名:
readme→readme(1) - 隐藏文件(以
.开头):.gitignore→ 主体.gitignore+ 后缀(1)→.gitignore(1)(和浏览器行为一致)
补充说明
- 预设的多扩展名集合可以根据实际需求扩展,比如加上特定业务场景的多层扩展名;
- 检查文件名是否存在时,要循环递增n(1、2、3…),直到生成的新文件名在目标目录中不存在为止。
内容的提问来源于stack exchange,提问作者QWerProg




