macos - 确定文件是否在任何 macOS 废纸篓文件夹中
问题描述
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.
*/
iCloud 同步文件夹上似乎也存在问题trashItemAtURL:
。
那么,我该如何解决呢?如果 Finder 可以检测到 iCloud 垃圾,我也应该可以。
(注意:我用来测试的应用程序甚至没有沙盒)
更多发现:也因死符号链接而失败
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:
操作,然后先检查返回的错误:
- 如果没有错误,则检查 if
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/"]
)
);
推荐阅读
- maven - maven jetty 如何打包一场战争?
- android - 如何使 MaterialButton 的波纹无边框
- c - C 指针错误 -> 表达式必须是可修改的左值
- c# - 自定义 IdentityDbContext 上的 UnitofWork 也不会保存更改当前用户始终为空
- php - 如何在 CentOS 的 PHP-7.3.9 中将 libxml2 升级到 2.9.9 版本?
- azure - 如果记录大小超过一些 MB,我的要求是显示能够删除的记录/日志在 azure 中最适合使用什么存储
- csv - 在 Pentaho Spoon 中读取一个平面文件,然后将其元数据导出为 CSV
- python - 如何在 django 中使用 multipart/form-data 编码返回图像二进制文件
- salesforce - Docusign 支持从 Salesforce 中的注释和附件迁移到文件
- php - 将 Dockerfile 从 php:7.2-fpm 更新为 php:7.3-fpm 时出错