具有外部 ntfs 的 Macos(默认只读)。Python os.walk 不会通过 ntfs 上的子目录进行递归

具有外部 ntfs 的 Macos(默认只读)。Python os.walk 不会通过 ntfs 上的子目录进行递归

配备 Macbook 2021 (arm64)。

uname -a
Darwin MacBook.local 21.1.0 Darwin Kernel Version 21.1.0: Wed Oct 13 17:33:01 PDT 2021; root:xnu-8019.41.5~1/RELEASE_ARM64_T6000 arm64

外部驱动器,SSD2TB,是 NTFS。

diskutil info disk4
   Device Identifier:         disk4
   Device Node:               /dev/disk4
   Whole:                     Yes
   Part of Whole:             disk4
   Device / Media Name:       External

   Volume Name:               SSD2TB
   Mounted:                   Yes
   Mount Point:               /Volumes/SSD2TB

   Content (IOContent):       None
   File System Personality:   NTFS
   Type (Bundle):             ntfs
   Name (User Visible):       Windows NT File System (NTFS)

最简单的测试就是简单地报告每个循环的目录名称,例如

python3
Python 3.10.1 (main, Dec 31 2021, 10:22:35) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, os.path
>>> os.chdir("/Volumes/SSD2TB/Photos")
>>> from glob import glob
>>> glob('*')
['Pictures']
>>> for d,dd,f in os.walk('.'): print(f"{dd}")
... 
[]
>>> os.path.isdir('Pictures')
True
>>> for d, dd, f in os.walk('.'):
...     print(f"{f}")
... 
['.DS_Store', 'Pictures']
>>> for d, dd, f in os.walk('.'):
...     print(f"{d}")
... 
.

是否有人理解为什么“。”中的子目录在 os.walk 中被报告为文件(通过在“f”变量中返回?并且应该是目录列表的“dd”变量返回一个空列表。

最后一点。如果我在本地驱动器上的路径中尝试相同的测试,则一切都会按预期运行。目录在变量“dd”中报告,文件在“f”中报告。

使用 pathlib2 的 iterdir() 与 'is_dir()' 将生成子目录和文件的列表,例如

dd = [x for x in Path(".").iterdir() if x.is_dir()]
f  = [x for x in Path(".").iterdir() if x.is_file()]

这适用于外部 ntfs 驱动器,因此 os.walk 在 macos 和 ntfs 的默认挂载中缺少某些内容。

答案1

我现在已经安装了 Paragon 软件的“NTFS for MAC”试用版,在经过一些安全检查后,我的外部 ntfs 驱动器已安装(R/W)。

for d, dd, f in os.walk("."):
    if re.match(r'.*?/\.@.*', d):
        continue
    print(f"{d}")

现在返回(如最初预期的那样)来自“。”的目录树。

例如

.
./Pictures
./Pictures/1998
./Pictures/1998/Barcelona
./Pictures/1998/Barcelona/.comments
./Pictures/2000

安装 ntfs-3g 也可能有效,但对于我的搭载操作系统“Monterey”的 Macbook 2021 (arm64) 来说,安装过程稍微复杂一些。

至少有解决方案。但 10 天后,费用将达到 19 美元。如果我继续需要以这种方式使用 NTFS 驱动器,那么与费力安装 ntfs-3g 相比,这笔费用可能值得。

因此,真正的罪魁祸首在于 Apple 选择呈现只读 NTFS 驱动器的方式以及 Python(os.walk)处理它的方式。

顺便说一句...我怀疑“Strawberry”音乐播放器也因为同样的原因拒绝扫描外部 NTFS 驱动器上的音乐文件夹。它只会返回一个空白库。

答案2

严格来说,这不是答案,而是一种替代解决方案。正如我在原始问题中所说,pathlib 的 Path.iterdir() 确实可以与原始 Apple ntfs 挂载一起使用。

因此,在此基础上,这里有一个 os.walk 的替代方案,它(在递归限制内)可以像 os.walk 一样工作。

import os, os.path, sys
from pathlib2 import Path

def pwalk(d):
    d = Path(d).resolve()
    dd = [ x for x in d.iterdir() if x.is_dir()]
    f  = [ x for x in d.iterdir() if x.is_file()]
    yield (d, dd, f)
    for xd in dd:
        yield from pwalk( d / xd)

因此,使用上面相同的案例,

for d, dd, f in pwalk('.'): print(f"{d}")
.
./Pictures
./Pictures/1998
./Pictures/1998/Barcelona
./Pictures/1998/Barcelona/.comments
./Pictures/2000

相关内容