外部硬盘上的某些文件夹和/或文件可在 Linux 上访问,但无法在 macOS 和 Windows 上访问

外部硬盘上的某些文件夹和/或文件可在 Linux 上访问,但无法在 macOS 和 Windows 上访问

我已经在外部 NTFS 驱动器上保存了一些视频,我的 Linux 系统可以正常观看。

当我尝试使用 macOS 来实现相同目的时,我正在寻找的文件夹却不见了。当时我身边没有 Linux 计算机,因此我尝试使用朋友的运行 Windows 10 的计算机访问该文件夹。

该文件夹在 Windows 10 上可见,但视频无法播放,并显示以下错误:

“…目录名称无效。”

也就是说,视频可以复制到 Windows 内置驱动器并从中播放。

稍后尝试在 Windows 中重命名文件夹时,我收到以下消息:

“此项不再位于“/media/cip/TOSHIBA_1TB/CINEMA/American_canada-australia/Charlie Chaplin”,请验证项目位置并重试。”

文件夹路径没有奇数字符(无论如何,我将在 Linux 中重命名该路径的所有文件夹并报告)。一些视频文件有带重音字符的法语名称,但这不应该是问题:Mac 全部是法语,其所有文件和文件夹都是法语,其他外部驱动器上的法语文件和文件夹也可以访问。


可能是什么原因?如何才能让它们在 macOS 系统上可见?

我已使用另一个 macOS 系统再次测试,但仍然看不到该文件夹​​。我将尝试在 Windows 上再次测试并在可以时进行更新。


编辑:我已从标题中删除了 NTFS 引用,因为该问题在具有其他类型格式的驱动器上也重现。

答案1

讨论文件/文件夹名称在 Windows 上的工作方式在微软网站上。然而,这仅提供了整体真相的一瞥。

注意:我会不是讨论“外部”系统访问 NTFS 卷的方式可能引起的代码页问题。我认为这在评论和其他答案中已经足够了。我将主要局限于以下两个方面:

至于文件系统,我将仅限于 NTFS,就像问题一样。请考虑来自上述链接网站的以下评论:

文件或目录名称不要以空格或句点结尾。尽管底层文件系统可能支持这样的名称,但 Windows shell 和用户界面才不是

现在,我们需要先搞清楚一些术语。我们处理各种...层,可能是一个合适的术语:

  • 文件系统,例如 NTFS
  • NT 对象管理器和其他内核工具,但说到名字大多对象管理器
    (如果你想查看它,可以使用类似程序运行对象
  • Win32 子系统(这就是上面所说的“Windows shell 和用户界面”)
  • 另一个“元方面”是操作系统版本,因为支持的路径长度可能有所不同

一个不错的解决方法是使用 Samba 共享,在客户端假装是 NTFS。但 Windows NTFS 卷也可以。我们将在 Windows 上从命令行“尝试”(按Win+R并输入cmd,然后按Enter)。

本地 NTFS 卷

假设我们想要创建一个无效的文件名(注意结尾的点?!):

echo NONSENSE > text.txt.

当尝试这样做时,结果确实是test.txt不是 test.txt.。Win32 子系统 (csrss.exe) 阻止我们做蠢事。嗯,很有趣,不是吗?

考虑一下另一个说法:

请勿使用以下保留名称作为文件名称:

CON,,,,,,,,,,,,,,,,,,,,,,,,和。还应避免在这些PRN名称后立即使用扩展名;例如,不推荐使用。​​​AUXNULCOM1COM2COM3COM4COM5COM6COM7COM8COM9LPT1LPT2LPT3LPT4LPT5LPT6LPT7LPT8LPT9NUL.txt

嗯,NUL听起来很有趣。我们知道这是从 Unixoid 系统上的替代品开始的/dev/null,继承自 DOS 时代。

echo NONSENSE > NUL

哦,对了。它是 的替代品/dev/null,所以输出会被吞掉。但是不使用听起来很诱人。那么让我们利用从Project Zero 博客文章,“本地设备”部分。

短暂的插曲:%CD%

如果您不太熟悉经典的 Windows 命令行 ( cmd.exe),特殊变量%CD%将为我们提供当前工作目录的绝对路径。请记住这一点,以便阅读下一节。因此,如果您当前在 中C:\test,该命令echo %CD%将产生输出C:\test。这是我们进行实验的便捷快捷方式。

从 Project Zero 文章中我们可以看出,在 Win32 子系统级别有很多方法可以避免路径名转换。其中一种方法是使用前缀,\\?\它在内部直接地转换为\??\,在较新的 Windows 版本中与 相同\GLOBAL??\。这称为对象目录(请不要将其与文件系统实体,尽管术语相似!)。同样,WinObj 和类似工具可让您调查对象管理器名称空间。

插曲:命名空间和终端服务器“内容”

任何看过 Windows NT 历史的人,以及那些追溯到 NT 的 Windows 10 的人,都会记得曾经需要单独授权终端服务。也就是说,能够远程连接到一台机器并允许不同的用户使用。

我认为是 Windows XP 最终通过允许同时使用多个用户帐户登录(“用户切换”)的方式将此功能带给了大众,并且可能 Windows 2000 或 2003 Server 在标准版本中包含了此功能,即使需要的 CAL 超出了默认包含的最低“席位”。

\??这就是和之间的区别的\GLOBAL??起源。\GLOBAL??是“DOS”设备名称的视图由全部登录会话。

\??如今,符号链接中也出现了这种现象(同样,不是文件系统实体!) 称为\DosDevices,这给出了关于其来源的线索。这是“DOS”设备名称(例如C:或网络驱动器映射)所在的位置。在现代系统上C:,反过来会是指向\Device\HarddiskVolume1(或类似)的符号链接。这通常是实际的由存储驱动程序堆栈中的某个驱动程序创建的设备对象,在本例中是应该是 NTFS 文件系统驱动程序。

因此,当您双击时,C:\Windows\explorer.exe内部发生的事情是路径被转换:

  • 在 Win32 子系统级别,通常的更改是在前面添加\??\
  • 然后对象管理器将展开\??\C:
    • 首先\??\进入您的登录会话的“DOS”设备命名空间(参见下面的注释)
    • 最终,对象管理器会计算出\??\C:类似于 的东西\GLOBAL??\C:,就像我们上面看到的一样,等同于\Device\HarddiskVolume1

然后,对象管理器将把路径的剩余部分传递\Windows\explorer.exe给负责设备对象的驱动程序\Device\HarddiskVolume1,确保驱动程序知道引用了哪个设备对象。并且该驱动程序将知道如何在其自己的命名空间内处理该路径的特定剩余部分。

评论:当您引用\??内部时,您最终会看到本地登录会话的“DOS”设备。这可以通过映射网络驱动器来最好地解释。假设您有一个X:为远程共享映射的驱动器号。假设您使用“用户切换”,或者这在一个强大的终端服务器上运行,其中另外 200 个用户同时登录。在这种情况下,我们面临两个问题。虽然系统驱动器(例如物理磁盘)可能由每个人共享,但销售部门的某个人可能已经映射了“销售份额”X:和来自开发部门的某个人可能已经映射了“开发共享”。这同样适用于通过 分配的“驱动器号” subst。这应该可以解释为什么不能有一个适合所有人的“DOS”设备名称的单一全局命名空间。

所以我们的目标是创造一个文件(或目录)命名NUL,而 Win32 子系统不允许我们这样做。它只是吞下输出,并且文件从未在我们的工作目录中创建。然而,利用上面链接的文章和之前的插曲中的信息,我们可以解决这个问题,通过发出以下命令来避开子系统级别的那些讨厌的路径转换:

echo NONSENSE > \\?\%CD%\NUL

提醒一下,%CD%扩展为当前工作目录的绝对路径,假设为C:\test,则上述命令等同于echo NONSENSE > \\?\C:\test\NUL

瞧,很快dir就证明文件已创建。如果我们用其他“保留”名称尝试,结果也很好。

请注意,您还可以使用实际的本机 NT 路径形式(\??而不是\\?)可达到相同效果:

echo NONSENSE > \??\%CD%\NUL

整洁的。

那么我们如何重新审视尾随的点尝试,但提供完整路径而不让 Win32 子系统干扰呢?:

echo ILLEGAL TRAILING DOT > \??\%CD%\test.txt.

瞧,它起作用了,下面快速dir /b证明一下:

C:\test>dir /b
CON
NUL
test.txt
test.txt.

插曲:UNC(通用命名约定)路径

这个主题在 Project Zero 文章中有更详细的处理,但可以说,有一种特殊形式的路径看起来与我们上面刚刚使用的非常相似:\\.\C:\Windows\explorer.exe就是一个例子。

还记得吗,每当你卡在登录屏幕上,记不住机器的本地机器名称时,它都会默认为其所属的域?一种简单的方法是参考当前机器甚至不使用其实际名称.\username,允许引用username用户当前机器

.可以\\.\C:\Windows\explorer.exe这样理解。实际上你所说的是\\. 在当前机器上 \C: 在驾驶中C:访问路径\Windows\explorer.exe......并且操作系统的不同功能相互配合以实现这一目标。

谨防:UNC 路径遵循一组不同的规则,这就是我仅提及它们的原因。如果您有兴趣了解更多详细信息,请阅读链接的文章和 Microsoft 文档的链接。

现在我们终于创建了一个“不可能”的文件test.txt.,让我们看一下它,好吗?

C:\test>type test.txt
NONSENSE

怎么回事?我清楚地记得我曾回响ILLEGAL TRAILING DOT过那个文件。

啊,当然。就像我们最初尝试创建时一样,test.txt.Win32 子系统再次介入并“有帮助地”将我们的名字转换为test.txt。所以我们实际上正在查看\??\%CD%\test.txt而不是\??\%CD%\test.txt.

因此应该这样做:

C:\test>type \??\%CD%\test.txt.
ILLEGAL TRAILING DOT

好多了。问题是,并非所有程序都能像 一样优雅地处理我们对 Win32 路径名转换的偷偷绕过cmd.exe。假设我们想打开记事本:

C:\test>notepad \??\%CD%\test.txt.

哇哦,我们看到了以下消息框:

警告消息框提示:文件名、目录名或卷标语法不正确。

因此,虽然有办法可以规避一些由于 Win32 子系统所施加的限制,这些方法的实用性有限且值得怀疑。

笔记:读者也发展Windows 上的软件可能还记得,使用前缀\\?\可以避开MAX_PATH限制(以前是 260,基本上是 255 加上\\?\终止符\0)。现在你知道为什么这允许我们使用大约32767 个字符。由于 UCS-2 已被 UTF-16 取代(我认为在 XP 中),对象管理器级别的路径修改只是一个问题。另一个问题是,在 UTF-16 中,代码点可能占用超过 16 位(又名wchar_tWCHAR),一旦您离开骨形态发生蛋白在后面。

无论如何,命令行(cmd.exe)为您提供了所有工具来访问和删除您首先能够从 Windows 创建的文件。

Linux/Samba 共享,假装是 NTFS

现在让我们离开本地驱动器并考虑Z:Samba 4.x 提供的映射网络驱动器,就 Windows 而言,它模拟 NTFS 驱动器。

映射网络驱动器 Z: 的驱动器属性,显示 Windows 将此视为 NTFS 驱动器

这个实验提供了更多的启发,因为我们可以按照 Linux 端的规则创建文件,而不必担心无法从 Windows 端访问它们。

  • 映射驱动器是Z:,我们将在Z:\testWindows 端
  • 在 Linux 端,该卷的格式为文件系统
    维基百科文章告诉我们,除了/\0(又名ASCII NUL 字符) 是允许的!所以这应该很有趣。

以下是一些奢侈的文件名,在 Windows 端应该(或至少可能)很难访问,使用 Linux 端的 Ubuntu 20.04 上的 Bash 来创建它们:

  • :.txt(使用 创建echo "$RANDOM" > \:.txt
  • ???.txt(使用 创建echo "$RANDOM" > \?\?\?.txt

答案2

我发布这个答案只是为了说明问题是如何解决的,从而总结一下对原始问题的评论,这可能对其他人有用。


我已经修复了 Linux 中创建这些文件夹的问题,只需缩短两个或三个视频文件的标题即可,这些视频文件的名称很长,但没有逗号、括号等明显的奇怪字符。我还更改了文件夹名称 — 尽管它们没有什么特别之处。将它们改回来并没有重现问题。

因此,要么是文件夹名称中包含一些在 Linux 上不可见的错误字符,要么是重命名的三个文件中的一些错误字符导致整个文件夹在 Mac 上不可见,并且全部其在 Windows 中无法播放。

最奇怪的是,在重命名文件夹和三个文件之前,没有任何文件可以在 Windows 中播放。

可能是这样,@Giacomo1968 在评论中说道

“...原始文件名中出现了一个‘幻影’字符......类似于回车符或不间断空格,在 Linux 中可以以一种方式处理,但在其他系统上却无法处理。”

问题是,在修复该问题之前,我曾尝试在 Windows 中播放除最终重命名的文件之外的其他文件。幻影角色也可能出现在文件夹名称中。


我又一次遇到了这种情况,在一个新驱动器上,该驱动器格式化为 exFAT,文件夹中有其他文件,在复制过程中,Nemo 文件管理器在 Linux 中报告了错误(例如“无法创建文件”),但实际上在 Linux 上一切正常。该文件夹在 Windows 中可见但完全无法访问(我不记得错误消息了,是文件或文件夹不存在),在 Mac 上可见,但只有一个文件不可见。在 Linux 中重命名文件夹和文件后同名一切正常!

我现在怀疑,问题中报告的最初问题以及创建错误的“幻影”角色的原因是复制过程中出现一些错误或粘贴标题从互联网页面复制的文本(例如,看起来像空格的东西实际上是其他东西)。我之所以会想到这一点,是因为在 Linux 中使用 Double Commander 进行复制时,它会报告一些名称的详细错误,这些名称中包含的空格可能是制表符或类似字符。

(为了避免从互联网上复制/粘贴选定文本时出现此类错误,可以使用类似Firefox 的“仅复制文本”插件可能非常有用。

最后,最好的复制解决方案是使用 Linux 中的 Double Commander,它可以非常清楚地指示有问题的文件名。

在命名文件或文件夹时复制/粘贴网络文本必须谨慎。

相关内容