【问题标题】:How to know character encoding of file names depending on the filesystem如何根据文件系统了解文件名的字符编码
【发布时间】:2012-09-02 15:26:51
【问题描述】:

我想知道文件系统中文件名的字符编码,以便在 GUI 中正确显示它们。

我应该怎么做?

我想我会根据文件系统(FAT、NTFS、ext3 等)获得不同的字符编码

谢谢

(我在 C++ 中工作,但这个主题与语言无关)

【问题讨论】:

  • 这取决于文件系统本身。有些文件系统支持字符编码,有些只支持一种。并且大多数不将编码存储在文件系统本身中,因为编码已经由其规范文档定义。您必须手动将这些信息存储在您自己的数据库中。
  • 这实际上取决于 API,因此取决于您使用的平台 (OS)。但是,在 C++17 中,文件系统标准库可能完整并包含在内,它应该可以以某种方式解决这个问题。

标签: filesystems filenames


【解决方案1】:

NTFS 是 Unicode (UTF-16)。 exFAT 也是 Unicode。

原始 FAT 和 fAT32 使用 OEM 字符集(在MSDN 上阅读更多信息)。

在 Linux 和 Unix 上,文件名可以包含除 NUL 之外的任何字节,并且未定义字符集。因此,每个应用程序自行决定使用哪一个。许多应用程序使用 UTF8。在this question 中查看更多信息。

上面的 unix 方法用于大多数文件系统(主要是因为“字符集”概念在操作系统级别上比在存储级别上更有意义)。您可以查看文件名字符here(表 2 第 3 列)的 FS 功能和要求。

【讨论】:

  • Unicode 是一种抽象表示,而不是字节表示。您需要一个编码来将 unicode 转换为字节。
  • @user803422 "Unicode" 在 Windows 中代表 UTF16。我已经更新了答案。
  • 在我的 Windows 7 - NTFS 驱动器上,文件名采用 UTF-8 格式。所以 UTF-16 不是一般规则。 MSDN的解释比较复杂。
  • @EugeneMayevski'Callback "Unicode" 在 Windows(以及 Java 和 JavaScript)中代表 WTF-16,如果有的话,据我所知 NTFS 确实允许在名称中使用不成对的代理。
  • @user803422 这似乎是不可能的,因为on-disk format 将文件名存储为计数序列 16 位小端整数。
【解决方案2】:

在 Linux 中运行以下命令:locale | egrep "LANG=" |切 -d 。 -f 2

在类 Unix 系统上,文件名的编码不是在文件系统级别设置的,而是在用户环境中设置的。例如,UTF-8 是 Ubuntu 中的默认设置。

在 Windows 上,默认编码是 CP-1252(AKA ISO-8859-1 或 Latin-1),但 FS 通过 UTF-16 编码使用 Unicode。见http://en.wikipedia.org/wiki/Filename

但如果你使用 Qt,你可以使用 Qt Creator 构建以下内容,结果是当前用户编码名称。

#include <QTextCodec>
#include <iostream>

using namespace std;
int main(int argc, char *argv[])
{
  Q_UNUSED(argc); Q_UNUSED(argv);
  QTextCodec* tc = QTextCodec::codecForLocale();

  cout << "Current names text codec: " << tc->name().data() << endl;
  return 0;
}

【讨论】:

  • ISO 8859-1 和 Latin-1 是一回事,但 Windows-1252/CP-1252 略有不同:“此编码是 ISO 8859-1 的超集,但与 IANA 的不同ISO-8859-1 通过使用可显示字符而不是 80 到 9F(十六进制)范围内的控制字符。” - Wikipedia
猜你喜欢
  • 2015-11-30
  • 2019-11-27
  • 2022-09-25
  • 2018-12-26
  • 2019-06-05
  • 1970-01-01
  • 2021-12-01
  • 2015-04-04
  • 2013-05-14
相关资源
最近更新 更多