3

我想使用 xattr 将一些元数据直接存储在我的文件上。这些本质上是我在搜索文件时用于文件分类的标签。我的目标是通过将更多信息与每个标签相关联来扩展通常的 Mac OS X 标签,例如添加该标签的日期,也许还有其他东西。

我正在考虑使用 .xattr 将 xattr 添加到文件中xattr -w。我的第一个猜测是在这个 xattr 值中存储类似 JSON 的东西,但我想知道

1) 我可以在 xattr 中存储的大小限制是多少?(xattr 的人是 vauge,指的是_PC_XATTR_SIZE_BITS我无法在任何地方找到的东西)

2) 将 JSON 格式的字符串存储为 xattr 有什么问题吗?

4

2 回答 2

5

根据man pathconf,有一个“可配置的系统限制或选项变量”_PC_XATTR_SIZE_BITS称为

用于存储最大扩展属性大小的位数(以字节为单位)。例如,如果文件系统支持的最大属性大小为 128K,则返回的值将是 18。但是值 18 可能意味着最大属性大小可以是 (256KB - 1) 到 128KB 之间的任何值。作为一种特殊情况,资源分叉可以有更大的大小,一些文件系统特定的扩展属性可以有更小和预设的大小;例如,Finder Info 总是 32 字节。

您可以使用这个用 Swift 4 编写的小型命令行工具来确定此参数的值:

import Foundation

let args = CommandLine.arguments.dropFirst()

guard let pathArg = args.first else {
  print ("File path argument missing!")
  exit (EXIT_FAILURE)
}

let v = pathconf(pathArg, _PC_XATTR_SIZE_BITS)

print ("_PC_XATTR_SIZE_BITS: \(v)")

exit (EXIT_SUCCESS)

我得到:

  • OS X 10.11 上 HFS+ 的 31 位
  • macOS 10.13 上的 64 位 APFS

作为用于存储最大扩展属性大小的位数。这意味着实际的最大 xattr 大小在范围内

  • 对于 OS X 10.11 上的 HFS+,1 GiB ≤ 最大值 < 2 GiB
  • 8 EiB ≤ 最大值 < 16 EiB 对于 macOS 10.13 上的 APFS
于 2018-07-25T12:25:27.263 回答
3

我似乎能够写至少 260kB,就像这样通过生成 260kB 的空值并将它们转换为字母a,以便我可以看到它们:

xattr -w myattr "$(dd if=/dev/zero bs=260000 count=1|tr '\0' a)" fred
1+0 records in
1+0 records out
260000 bytes transferred in 0.010303 secs (25235318 bytes/sec)

然后读回它们:

xattr -l fred 
myattr:  aaaaaaaaaaaaaaaaaa...aaa

并检查返回的长度:

xattr -l fred | wc -c
260009

我怀疑这实际上是命令行上 ARGMAX 的限制:

sysctl kern.argmax
kern.argmax: 262144

此外,仅仅因为您可以将 260kB 存储在一个xattr中,这并不意味着它是可取的。我不知道 HFS+,但是在一些 Unixy 文件系统上,属性可以直接存储在 inode 中,但是如果超过一定的限制,则必须在磁盘上为数据分配额外的空间。

————

随着High SierraAPFS替换的出现HFS+,请务必在两个文件系统上进行测试 - 还要确保Time Machineditto也备份和恢复数据,并且在复制/移动/归档文件时确保诸如tar和 Finder 等实用程序传播它们.

还要考虑通过电子邮件发送标记文件或将其复制到 FAT 格式的 USB 记忆棒时会发生什么。


我还尝试在单个文件上设置多个属性,以下脚本成功地将 260kB 的 1,000 个属性(称为attr-0attr-1... attr-999)写入单个文件 - 这意味着该文件有效地携带 260MB 的属性:

#!/bin/bash
for ((a=1;a<=1000;a++)) ; do
   echo Setting attr-$a
   xattr -w attr-$a "$(dd if=/dev/zero bs=260000 count=1 2> /dev/null | tr '\0' a)" fred
   if [ $? -ne 0 ]; then
      echo ERROR: Failed to set attr
      exit
   fi
done

这些都可以看到和读回 - 我检查了。

于 2017-11-17T16:06:25.537 回答