簡體   English   中英

確定文件是否在任何 macOS Trash 文件夾中

[英]Determine if a file is inside any macOS Trash folder

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.
 */

trashItemAtURL: on iCloud- trashItemAtURL:似乎也存在問題

那么,我該如何解決這個問題? 如果 Finder 可以檢測到 iCloud 垃圾,我也應該可以。

(注意:我用來測試的應用程序甚至沒有被沙盒化)

更多發現:也因死符號鏈接而失敗

官方建議的使用getRelationship:方法getRelationship:如果 url 指向目標不存在的符號鏈接,也會失敗並顯示錯誤。

所以,基本上,這個功能很糟糕(在 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:]甚至會因符號鏈接損壞而失敗,我得出結論,這是 macOS 中多年來未被發現的錯誤。

我想出了以下解決方法:

使用getRelationship:操作,然后先檢查返回的錯誤:

  • 如果沒有錯誤,則檢查是否relationship == NSURLRelationshipContains ,並將其用作我的結果。
  • 否則,如果出現任何錯誤,請檢查路徑是否包含“/.Trash/”或“/.Trashes/” - 如果是,則假設該項目位於 Trash 文件夾內。
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/"]
                                )
                  );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM