大小写敏感(case sensitive)或大小写不敏感(case insensitive)是软件开发中常常被忽略而又偶尔造成困扰的基础问题。这里做一个简单的问题汇总。
先扫个盲:
- 所谓大小写是否敏感,即是否区分大小写,敏感意味着区分,不敏感意味着不区分。
- “大小写不敏感但大小写保留(case preserving)”,是指操作系统虽然把
abc
和ABC
视为同一个文件或文件夹,但内部保留区分,如果已经存在abc.txt
,则无法再新建ABC.TXT
。
系统是否区分大小写
某个操作系统是否区分大小写,取决于实际使用的文件系统(常见操作系统的文件系统,参见附录)。
像 macOS,在格式化磁盘时支持选择多种文件系统格式,同时也支持选择【区分大小写】、【日志式】、【加密】等配置,如果没有手动更改,默认不区分大小写。Windows 的 NTFS 默认不区分大小写,如果使用了 WSL,那对应的 Linux 子系统区分大小写。
- Windows 使用的 NTFS 和 FAT 系列文件系统,默认大小写不敏感但大小写保留
- macOS 使用的 APFS 和 HFS+ 文件系统,默认大小写不敏感但大小写保留
- Linux 使用的 ext3/ext4 文件系统,默认大小写敏感
在 Git 中的实践
Git 默认不区分文件名大小写,如果平常不注意文件的大小写,在实际使用中可能会遇到这样的问题:
-
代码仓库中存在路径为
timeLine/TimeLine.jsx
的文件,本地修改为timeline/Timeline.jsx
,执行git status
不会提示文件改动。 -
团队中有人在 Linux 系统上开发,他无视了已经存在的
timeLine/TimeLine.jsx
文件,创建了新的timeline/Timeline.jsx
文件,并提交到了部署在 Linux 上的 Git 服务器。 -
Git 服务器上同时存在
timeline/Timeline.jsx
和timeLine/TimeLine.jsx
文件,在 Windows 或 macOS 上开发的人,无法正常拉取到两个文件。
因此强烈建议关闭 Git 的忽略大小写功能:
# 全局设置
git config --global core.ignorecase false
# 只设置当前仓库
git config core.ignorecase false
在 Windows 或 macOS 上重命名大小写时,使用 git mv
:
git mv --force TimeLine.jsx Timeline.jsx
# `--force` 可以简写成 `-f`
git mv -f TimeLine.jsx Timeline.jsx
在 webpack 中的实践
由于 Windows 和 macOS 默认不区分大小写,对于文件 fileName.js
,以下几行代码 webpack 编译不会报错:
require('fileName.js')
正确的文件名require('FileName.js')
写错文件名require('filename.js')
写错文件名
但是使用部署在 Linux 上的 CI/CD 工具时,webpack 会无法找到后两行代码引用的模块。
因此建议安装 case-sensitive-paths-webpack-plugin 插件,强制检查文件路径大小写。
HTTP Header 区分大小写吗
HTTP Header 的名称字段不区分大小写。HTTP/2 多了额外的限制,因为增加了头部压缩,要求在编码前必须转成小写。
HTTP/1.1 [RFC 7230] 中的描述:
Each header field consists of a case-insensitive field name followed by a colon (":"), optional leading whitespace, the field value, and optional trailing whitespace.
HTTP/2 [RFC 7540] 中的描述:
Just as in HTTP/1.x, header field names are strings of ASCII characters that are compared in a case-insensitive fashion. However, header field names MUST be converted to lowercase prior to their encoding in HTTP/2. A request or response containing uppercase header field names MUST be treated as malformed (Section 8.1.2.6).
HTTP Method 区分大小写吗
HTTP Method 区分大小写,且全部大写。
HTTP/1.1 [RFC 7230] 中的描述:
The method token indicates the request method to be performed on the target resource. The request method is case-sensitive.
URL 区分大小写吗
HTTP 协议和域名不区分大小写,path
/query
/fragment
区分。
HTTP/1.1 [RFC 7230] 中的描述:
The scheme and host are case-insensitive and normally provided in lowercase; all other components are compared in a case-sensitive manner.
更具体的描述需要参考 URL 的相应标准 Uniform Resource Identifier (URI): Generic Syntax [RFC 3986]
邮箱地址区分大小写吗
参考 URL 标准,邮箱中的域名不区分大小写。用户名是否区分大小写,取决于电子邮件服务商。
HTML 区分大小写吗
HTML 标签、属性名称等一般不区分大小写,具体参考 HTML Living Standard。
CSS 区分大小写吗
CSS 属性名称不区分大小写,具体参考 CSS Syntax Module Level 3 和更细致的 CSS 模块标准。
附录
常见文件系统
- Microsoft 系
- FAT, File Allocation Table 主要应用于 MS-DOS 系统
- FAT12
- FAT16 不支持 2G 及其更大的文件
- FAT32 适用于闪存,不支持 4G 及其更大的文件,容易产生磁盘碎片,需要定期进行磁盘碎片整理
- exFAT, Extended File Allocation Table 主要应用于 Windows NT 内核系统,不是日志文件系统,使用过程中断电可能会导致数据丢失
- HPFS, High Performance File System 主要应用于由 Microsoft 和 IBM 开发的 OS/2 操作系统
- NTFS, New Technology File System 日志文件系统,主要应用于 Windows NT 内核系统
- ReFS, Resilient File System 适用于 Windows Server 服务器
- FAT, File Allocation Table 主要应用于 MS-DOS 系统
- Apple 系
- MFS, Macintosh File System 主要应用于 Mac OS 系统
- HFS, Hierarchical File System 主要应用于 Mac OS 系统
- HFS+, Hierarchical File System Plus 主要应用于 Mac OS 系统,在系统中显示为“Mac OS Extended(Mac OS 扩展)”,支持日志
- APFS, Apple File System 主要应用于 macOS 系统,优化闪存/SSD 存储
- Linux 系
- ext, extended filesystem 非日志文件系统
- ext2, second extended filesystem 非日志文件系统
- ext3, third extended filesystem 日志文件系统
- ext4, fourth extended filesystem 日志文件系统
- Unix 系
- XFS, XFS File System 由 Silicon Graphics 为 IRIX 操作系统开发
- ZFS, Zettabyte File System 最初由 Sun 公司为 Solaris 10 操作系统开发