繁体   English   中英

无法使用 NSDirectoryEnumerator 删除我的主目录中的目录内容

[英]Unable to delete the contents of a Directory in my Home Directory using NSDirectoryEnumerator

我一直无法使用 NSDirectoryEnumerator 删除目录的内容。

这是我的方法:

- (BOOL) deleteDirectoryContents:(NSString *)directoryPath
{
    BOOL success = FALSE;
    BOOL isDir;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:directoryPath isDirectory:&isDir] && isDir)
    {
        NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:directoryPath];
        NSLog(@"dirEnum in deleteDirectoryContents is %@", dirEnum);
        NSString *documentsName;
        // NSLog(@"[dirEnum nextObject] is: %@", [dirEnum nextObject]);
        while (documentsName = [dirEnum nextObject])
        {
            NSString *filePath = [directoryPath stringByAppendingString:documentsName];
            NSLog(@"filePath is: %@", filePath);
            BOOL isFileDeleted = [fileManager removeItemAtPath:filePath error:nil];
            if(isFileDeleted == NO)
            {
                NSLog(@"All Contents not removed");
                success = FALSE;
                break;
            }
            success = TRUE;
        }
        if (success) NSLog(@"All Contents Removed");
    }
    return success;
}

这是我在主程序中的代码:

NSString *testDir = @"/Users/grinch/MyTestTemp";
//testDir = [NSHomeDirectory() stringByAppendingPathComponent:  @"MyTestTemp"];
NSLog(@"testDir is: %@", testDir);
BOOL result = [self deleteDirectoryContents:testDir];
NSLog(@"result is: %d", result);

这是我的控制台 output:

testDir is: /Users/grinch/MyTestTemp
dirEnum in deleteDirectoryContents is <NSAllDescendantPathsEnumerator: 0x60000008c300>
result is: 0

我还检查了[dirEnum nextObject]的值(通过在我的代码中取消注释 NSLog 语句)。 它返回 null。 而且我从来没有看到“filePath is” NSLog 语句。 所以内部的while循环永远不会执行。

是的,该目录(带有文件)确实存在于我的主目录中。 我创建了这些文件。 我有权限。 我可以使用 Finder 轻松删除此目录中的文件

我错过了什么?

PS我做了更多的测试。 看起来我在 Xcode 中的简单程序没有访问我主目录中文件和文件夹的权限。 为什么? 我不知道。

这是我的附加测试代码:

NSError *errorMsg;
[[NSFileManager defaultManager] removeItemAtPath:@"/Users/grinch/myTestTemp/Hello.txt" error:&errorMsg];
if (errorMsg) NSLog(@"ERROR - File delete errorMsg is: %@", errorMsg);
    
success = [[NSFileManager defaultManager] removeItemAtPath:testDir error:&errorMsg];
if (errorMsg) NSLog(@"ERROR - Folder delete errorMsg is: %@", errorMsg);}

这是我的控制台 output:

2022-09-10 09:56:48.958352-0400 NSAlert[97106:7511815] ERROR - File delete errorMsg is: Error Domain=NSCocoaErrorDomain Code=513 "“Hello.txt” couldn’t be removed because you don’t have permission to access it." UserInfo={NSFilePath=/Users/grinch/myTestTemp/Hello.txt, NSUserStringVariant=(
), NSUnderlyingError=0x6040006421f0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
2022-09-10 09:56:48.960560-0400 NSAlert[97106:7511815] ERROR - Folder delete errorMsg is: Error Domain=NSCocoaErrorDomain Code=513 "“MyTestTemp” couldn’t be removed because you don’t have permission to access it." UserInfo={NSFilePath=/Users/grinch/MyTestTemp, NSUserStringVariant=(
), NSUnderlyingError=0x60400045ff80 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

所以我的问题是:

  1. 为什么目录枚举器不起作用?
  2. 为什么 Xcode 没有权限删除我的主文件夹中的项目?
  3. 如何赋予 Xcode 删除主目录中项目的能力(或权限)?

我在上面的deleteDirectoryContents:方法中发现了一个错误。 结果,回答了我的大部分问题!

一、声明NSString *filePath = [directoryPath stringByAppendingString:documentsName]; 在while循环中将不起作用。 必须在文件名之前插入/ 所以该行应该是NSString *filePath = [directoryPath stringByAppendingFormat:@"/%@",documentsName];

现在方法deleteDirectoryContents:将按预期工作。

这是固定方法的代码:

- (BOOL) deleteDirectoryContents:(NSString *)directoryPath
{
    BOOL success = FALSE;
    BOOL isDir;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:directoryPath isDirectory:&isDir] && isDir)
    {
        NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:directoryPath];
        NSLog(@"dirEnum in deleteDirectoryContents is %@", dirEnum);
        NSString *documentsName;
        // NSLog(@"[dirEnum nextObject] is: %@", [dirEnum nextObject]);
        while (documentsName = [dirEnum nextObject])
        {
            NSString *filePath = [directoryPath stringByAppendingFormat:@"/%@",documentsName];
            NSLog(@"filePath is: %@", filePath);
            NSError *errorMsg = nil;
            BOOL isFileDeleted = [fileManager removeItemAtPath:filePath error:&errorMsg];
            if (errorMsg) NSLog(@"ERROR - Failed to delete file or folder at: %@.  Error message is: %@", filePath, errorMsg);
            if(isFileDeleted == NO)
            {
                NSLog(@"All Contents not removed");
                success = FALSE;
                break;
            }
            success = TRUE;
        }
        if (success) NSLog(@"All Contents Removed");
    }
    return success;
}

而且我可以确认,如果您的 Xcode 程序创建目录和其中的文件,该程序还可以使用deleteDirectoryContents:取决于最初创建文件夹的位置。

如果程序在临时目录(例如缓存目录)而不是用户主文件夹中创建文件夹和文件,则它可以工作。 但由于权限和沙盒, deleteDirectoryContents:在 Xcode 中运行程序时,似乎不适用于用户主目录中程序创建的文件夹和文件。

PS我使用以下内容获取临时目录名称:

- (NSString *) get_temporary_dir
{
    NSString *path = nil;
    NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    if ([paths count]) {
        path = [[paths objectAtIndex:0] stringByAppendingPathComponent:bundleName];
    } else {
        path = NSTemporaryDirectory();
        path = [path stringByAppendingPathComponent:bundleName];
    }
    return [[[NSString alloc] initWithUTF8String:[path UTF8String]] autorelease];
}

然后程序使用该名称创建临时目录。 该程序在该临时目录中创建了一些文件,然后能够使用上面的deleteDirectoryContents:方法删除它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM