【问题标题】:Set modification date on symbolic link in Cocoa在 Cocoa 中的符号链接上设置修改日期
【发布时间】:2012-05-23 10:28:20
【问题描述】:

在 Cocoa 中,我想设置符号链接的修改日期。

使用[NSFileManager setAttributes:ofItemAtPath:error:] 可以很好地处理常规文件,但不适用于符号链接。

我怎样才能做到这一点?

【问题讨论】:

    标签: macos cocoa attributes symlink nsfilemanager


    【解决方案1】:

    没有办法直接用 NSFileManager 来做。 setAttributes:ofItemAtPath:error: 方法封装了一堆基于 BSD 路径的函数,如 utimes、setxattr、chown 等,所有这些函数都遵循符号链接而不是直接对它们进行操作。

    一个明显的选择是手动下拉到 BSD 层。一些函数具有“不遵循符号链接”的版本,例如 lchown,但并非所有函数都这样做。特别是,改变 mod 时间的那个,utimes,没有。因此,您必须打开文件并使用基于 fd 的变体 futimes。代码如下所示:

    int fd = open([NSFileManager fileSystemRepresentationWithPath:path], O_RDONLY | O_SYMLINK);
    futimes(fd, 0);
    close(fd);
    

    如果你打算做很多这样的事情,你可以编写自己的 setAttributes:ofSymlinkAtPath:error: 实现在 NSFileManager 的一个类别中,它包含了 futimes、fchflags、fsetxattr 等。

    唯一真正的问题是您需要对符号链接本身具有读取访问权限(以及修改 mod 时间所需的任何访问权限等)才能使其工作,但这通常不是问题,据我所知,OS X 无论如何也无法解决它。 (Linux 确实允许您打开一个既不读取也不写入访问的文件,只是为了进行 f* 调用,但 BSD 不允许。)

    作为另一种选择,我相信 NSURL 文件 URL API 确实不遵循符号链接,这意味着这应该可以工作(但我现在不在我的 Mac 前,所以我不能测试):

    [[NSURL fileURLWithPath:path isDirectory:NO] setResourceValue:[NSDate date] forKey:NSURLContentModificationDateKey error:nil];
    

    【讨论】:

    • 感谢您的完整回答。不幸的是,NSURL 的东西似乎不起作用,但是 futimes 让我很感兴趣。第二个参数是一个 struct timeval,但它只包含秒......如果我输入例如 50000 秒,则文件日期根本不会改变。我做错什么了吗?
    • NSURL 终于完美运行了!唯一的事情是用简单的日期替换 [NSDate date]。谢谢!!
    • 抱歉耽搁了;发布此答案后不久,我休假了一周。第二个参数是两个 struct timeval 的数组(衰减为指向 struct timeval 的指针),而不是 struct timeval。如果传递 0,则使用当前时间。手册页应该解释所有这些。
    • 我不确定您所说的“将 [NSDate date] 替换为简单的日期”是什么意思。这里的论点是一个 NSDate*。如果你碰巧有一个你想使用的叫做“日期”的东西,当然你可以通过它。传递“[NSDate date]”将使用当前时间。
    猜你喜欢
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2021-06-16
    • 1970-01-01
    • 2014-05-07
    相关资源
    最近更新 更多