2012-07-04 41 views
3

NSFileManager removeItemAtURL仅执行递归删除。对非空目录没有特殊的处理。检查目录为空或者仅当空除去在Objective-C

我怎样才能通过事先测试条件只删除空目录?有contentsOfDirectoryAtPath可以获得文件列表,这些文件可能是空的,但这太过于夸张。

或者,有没有只有当空,除去它,就像好醇” rmdir的功能?嗯,我可以称之为...

回答

6

你必须使用,如果你想留在基金会的土地,没有其他办法。

但是,如果你这样做你介绍一个竞争条件:在您列出目录的内容,并删除之前的一些其他程序可以写有一个新的文件,然后被删除。所以你必须接受这个事实,即你正在删除包括他们所有内容的文件夹,或者你必须寻找一个不同的API。

您可以使用POSIX rmdir功能来实现你的目标是这样的:

NSString *path = [url path]; 
int result = rmdir([path fileSystemRepresentation] ); 
if (result == 0) // everything ok 
else // lookup error code from errno 

如果目录不是空你的错误代码ENOTEMPTY

+0

嘿,我刚刚在提交答案的一秒钟内编辑提问'rmdir'的问题。这可能是最好的方式,即使我在iPhone上。 +1 – Potatoswatter

+0

即使是我建议的东西,我也+1。仅仅因为你在iPhone上并不意味着使用POSIX库调用会有什么问题 - 我更喜欢他们自己为大多数事情设置“基础”。 –

+0

@JasonCoco POSIX很棒,但这是我第一次参加基金会,所以我比其他人更坚持这一点,仅仅为了教育。但iPhone确实意味着将不存在文件系统竞争条件。 – Potatoswatter

0

为什么不实施NSFileManager委托方法"fileManager:shouldRemoveItemAtURL:",并在该委托方法实现中,做一个快速检查,看看是否A)该项目是一个目录和B)如果该目录之前是空的返回“YES”。

+0

这不是一个答案,也不要一个很好的建议。我应该用一个全局委托方法替换一个特定的'if'语句,也许关闭一个不同的文件,仲裁删除所有内容? – Potatoswatter

+0

是的,这是一个很好的答案和一个很好的建议。在“'remoteItemAtURL'”时间,NSFileManager在执行删除操作之前调用该委托方法*,以确定是否可以删除某些内容。在你的情况下,你只想删除通过一定标准的东西。例如。空目录。对于我自己的代码,我宁愿依赖Cocoa框架提供的内容,但是听起来你更喜欢直接使用C/UNIX/POSIX的东西。所以+1给Sven的上级答案。 –

+0

我问如何检查一个目录是否为空。你的建议是建立一个新的函数,它需要一个URL并检查它是否是一个空目录。没有答案。 – Potatoswatter

2

这不是矫枉过正...如果你想要的是像- isEmptyDirectoryAtURL:的方法,只是使它:

@interface NSFileManager (EmptyDirectoryAtURL) 
- (BOOL)isEmptyDirectoryAtURL:(NSURL*)url; 
@end 

@implementation NSFileManager (EmptyDirectoryAtURL) 

- (BOOL)isEmptyDirectoryAtURL:(NSURL*)url 
{ 
    // This assumes you know the URL you have is actually a 
    // directory and should be enhanced to ensure that 
    return ([[self contentsOfDirectoryAtURL:url includingPropertiesForKeys:nil options:0 error:NULL] count] <= 1); 
} 

@end 
+0

为什么一个项目被允许? – Potatoswatter

+0

@Patatoswatter如果URL不存在,它将返回0,但如果URL存在并且为空,那么魔术自引用将成为返回内容('.'目录)的一部分,所以它会实际上如果它在那里并且是空的,它总是1。你可以通过一个选项来排除隐藏的文件,其中包括'.',但是你的目录实际上不是空的,所以最好不要清空。 –

+0

谢谢! +1(dot dot dot) – Potatoswatter