我已经在JVM和Rust的库中实现了这样的功能。这是我学到的:
处理应用程序名称,因为您的用户不能或不会。
提供计算配置、缓存等目录的完整路径(包括应用程序名称!)的 API。不这样做将导致代码在 3 个主要平台中的至少 2 个上保证是错误的,因为约定差异很大。
考虑由MegaCorp公司(网址MegaCorp.co.uk)编写的名为Foo App的应用程序。在 Linux 下,命名应用程序的路径段应该是fooapp/
(小写,没有空格),在 Windows 上应该是MegaCorp\Foo App\
(注意两个文件夹),在 macOS 上应该是uk.co.MegaCorp.Foo-App
(无效字符替换为-
)。
对每个目录的用途都有明确的定义。
例如,我的库runtimeDir
在 macOS 或 Windows 上不提供 a,因为它与在 Windows 上XDG_RUNTIME_DIR
非常不同%TEMP%
。
这是一个潜在的安全问题来源,因为 Linux 上的运行时目录保证它只能由所有者访问,在用户注销时被删除等。
另外,我只fontDir
在 Linux 和 macOS 上提供。Windows 确实有一个字体目录,但与 Linux 和 macOS 不同,它不是用户可写的。
另一方面,我在所有三个平台上同时提供dataDir
( %APPDATA%
) 和dataLocalDir
( )。%LOCALAPPDATA%
在 macOS 和 Linux 上,这些目录返回相同的路径——这是一个明确的设计决策,考虑到如果其中一个目录不可用,用户将如何编写代码:用户要么忘记处理它,要么只是退回到另一个目录。通过选择的设计,这只是开箱即用,用户无需考虑。
在用户遇到问题之前避免问题。
这就是为什么一般缓存、配置等目录路径返回%LOCALAPPDATA%
and %APPDATA%
,但应用程序特定的缓存和配置目录路径返回%LOCALAPPDATA%\Company\Application\cache
and %APPDATA%\Company\Application\config
。
注意子目录!这是为了保证应用程序的缓存、配置和数据目录的干净分离,无论用户可能有什么奇怪的 Windows 设置。
将用例拆分为单独的模块。
我的库中有三个不同的模块,具有明确定义的独立用例:
BaseDirs,它查询用户不可见的标准目录(缓存、配置、数据、可执行文件、运行时目录)的路径,并强烈建议改用ProjectDirs。
ProjectDirs,它为您自己的应用程序或项目计算缓存、配置或数据目录的位置,这些目录派生自标准目录。
UserDirs,它查询面向用户的标准目录(音频、文档、下载等)的路径。
虽然BaseDirs
并且UserDirs
有相当无趣的构造函数(new()
),但ProjectDirs
提供了这个工厂方法:
ProjectDirs::from(qualifier: &str, organization: &str, application: &str)
此方法可确保用户最终获得到其应用程序缓存、配置等目录的正确、符合标准的路径,而无需了解每个单独平台的所有复杂性。
最后一个建议:我会保留一个名为“XDG Basedir Library”的库,专注于 Linux,并发布一个更通用名称的库,如处理 Linux、Windows 等的“标准目录库”以避免混淆。
希望这有帮助!