macos - 确定文件是否在任何 macOS 废纸篓文件夹中

标签 macos icloud icloud-documents

有一个similar question for iOS ,但我发现建议的解决方案并非在所有情况下都适用于 macOS。
在 Mac 上,有许多可能的废纸篓文件夹:

  • /.Trashes
  • ~/.Trash
  • ~/Library/Mobile Documents/com~apple~CloudDocs/.Trash – 这个来自 iCloud
  • /Users/xxx/.Trash – 任何其他用户的垃圾
  • /Volumes/xxx/.Trashes

  • 此代码应该有效,但不适用于 iCloud 垃圾箱:
    NSURL *theURL = ...;
    NSURLRelationship relationship = NSURLRelationshipOther;
    NSError *error = nil;
    [NSFileManager.defaultManager
             getRelationship: &relationship
                 ofDirectory: NSTrashDirectory
                    inDomain: 0
                 toItemAtURL: theURL
                       error: &error];
    BOOL insideTrash = !error && (relationship == NSURLRelationshipContains);
    
    如果 URL 指向任何 iCloud 文件夹(包括上面显示的垃圾箱文件夹),我会收到以下错误:
    Error Domain=NSCocoaErrorDomain Code=3328
    "The requested operation couldn’t be completed because the feature is not supported."
    
    奇怪的是,即使是 10.15 SDK 中“NSFileManager”的头文件也建议使用相同的代码:
    /* trashItemAtURL:resultingItemURL:error: [...]
    
        To easily discover if an item is in the Trash, you may use
        [fileManager getRelationship:&result ofDirectory:NSTrashDirectory
           inDomain:0 toItemAtURL:url error:&error]
        && result == NSURLRelationshipContains.
     */
    
    好像还有一个issue with trashItemAtURL: on iCloud-synched folders .
    那么,我该如何解决呢?如果 Finder 可以检测到 iCloud 垃圾,我也应该可以。
    (注意:我用来测试的应用程序甚至没有沙盒)
    更多发现:也因死符号链接(symbolic link)而失败
    官方推荐的使用方法getRelationship:如果 url 指向目标不存在的符号链接(symbolic link),也会失败并出现错误。
    所以,基本上,这个功能已经很糟糕了(在 10.13.6、10.15.7 和 11.0.1 中得到了验证)。
    这是演示该错误的代码,我在 FB8890518 下向 Apple 提交了该代码:
    #import <Foundation/Foundation.h>
    
    static void testSymlink (NSString* symlinkName, NSString* symlinkTarget)
    {
        NSString *path = [[NSString stringWithFormat:@"~/.Trash/%@", symlinkName] stringByExpandingTildeInPath];
        NSURL *url = [NSURL fileURLWithPath:path];
        symlink (symlinkTarget.UTF8String, path.UTF8String);
        NSLog(@"created symlink at <%@> pointing to <%@>", url.path, symlinkTarget);
    
        NSURLRelationship relationship = -1;
        NSError *error = nil;
        [NSFileManager.defaultManager getRelationship:&relationship ofDirectory:NSTrashDirectory inDomain:0 toItemAtURL:url error:&error];
        NSString *rel = @"undetermined";
        if (relationship == 0) rel = @"NSURLRelationshipContains";
        if (relationship == 1) rel = @"NSURLRelationshipSame";
        if (relationship == 2) rel = @"NSURLRelationshipOther";
        NSLog(@"result:\n relationship: %@\n error: %@", rel, error);
    }
    
    int main(int argc, const char * argv[])
    {
        @autoreleasepool {
            testSymlink (@"validSymlink", @"/System");
            testSymlink (@"brokenSymlink", @"/nonexisting_file");
        }
        return 0;
    }
    

    最佳答案

    意识到[NSFileManager getRelationship:]甚至因符号链接(symbolic link)损坏而失败,我得出的结论是,这是 macOS 中的一个错误,多年来一直未被发现。
    我想出了以下解决方法:
    使用 getRelationship:操作,然后先检查返回的错误:

  • 如果没有错误,则检查是否relationship == NSURLRelationshipContains ,并将其用作我的结果。
  • 否则,如果出现任何错误,请检查路径是否包含“/.Trash/”或“/.Trashes/” - 如果是,则假定该项目位于“垃圾箱”文件夹中。
  • NSURL *theURL = ...;
    NSURLRelationship relationship = NSURLRelationshipOther;
    NSError *error = nil;
    [NSFileManager.defaultManager
             getRelationship: &relationship
                 ofDirectory: NSTrashDirectory
                    inDomain: 0
                 toItemAtURL: theURL
                       error: &error];
    BOOL insideTrash =   !error && (relationship == NSURLRelationshipContains)
                       || error && (
                                        [theURL.path containsString:@"/.Trash/"]
                                     || [theURL.path containsString:@"/.Trashes/"]
                                    )
                      );
    

    关于macos - 确定文件是否在任何 macOS 废纸篓文件夹中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64663834/

    相关文章:

    git - iCloud Drive 桌面同步与 Git - 已删除的文件重新出现并带有数字后缀的重复项

    ios - 与我的应用关联的文件类型

    c++ - Mac Qt C++ 上的 lldb

    java - 让 jsvc 在 OSX 上工作

    ios - UIDocument中如何实现文件协调

    icloud - 我如何(以及何时)在 CKRecord 上使用 iCloud 的 encodeSystemFields 方法?

    C# Mono {new Bitmap ("fileName");} 卡在 OSX 上

    ios - 如何在 Swift 3 中将 NSMapTable 与字符串键一起使用?

    ios - 应用程序使用的 iCloud 存储空间?