问题
Say I've got a folder in my iOS app's data directory with several thousand small files in it. Deleting this folder (via [NSFileManager removeItemAtPath]
) takes a nontrivial amount of time. But on OS X, deleting a folder with the same contents is very fast. It seems to simply unlink the folder from the filesystem. So why does iOS take so long? What is the difference?
Edit: On an iPad 3, deleting 3 folders with 5,000 to 9,000 files each takes about 35 seconds. On the simulator running on an older Retina MBP, it takes about 1.5 seconds.
回答1:
The hierarchical structure that you see is not "real" -- directories are not physical containers for the files that they appear to contain. The directory hierarchy is a carefully maintained fiction.
Irrelevant aside: The original Mac file system took this a step further -- it made the directory structure totally a visual fiction -- all of the files were at the root of the (3.5") floppy) disk, and only seemed to be arranged in folders. Thankfully this was supplanted by HFS.
It is better to think of directories/folders as a special kind of file that contains an index to a set of files that it is going to pretend to contain.
Conceptually, this works much like classical Cocoa memory management. Each (directory/object) "owns" a set of (files/objects) by reference ("retains" the (file/object)).
When you delete a file from a directory, it is "released". If no other directory has an ownership claim on that file, it is "dealloc'ed".
Your (folder/object) doesn't contain the objects that it "owns". It doesn't really even "own" them -- it just has a "ownership claim" on them.
From Wikipedia's article about Hard Links:
"a hard link is a directory entry that associates a name with a file on a file system. A directory is itself a special kind of file that contains a list of such entries."
Note that due to the use of hard links it is possible to have a single physical file that can appear in multiple directories. Each one of those directories owns a reference to the "real" file. Each reference is as "real" as any other. All references have to be "unlinked" for the file to be marked as deleted.
The "file" can even have different "names" in the different directories!
Hard links are the chain saw of filesystem features -- powerful, but potentially quite dangerous. Note that the OSX GUI provides no means of producing hard links, or even symlinks.
From this email list item.
Now about iOS
[NSFileManager removeItemAtPath: error:], what it does under the hood is they iterate through the subdirectories and files and delete them first. This takes some time. I am interested if it is possible to do this instantly, without even implicit recursion. Just remove the directory and the files and subdirectories would disappear?
what you can do is
If you're worried about the time this would take and you need an instant results you could rename the folder (which is virtually instantaneous) then remove the renamed folder and it's contents in a background thread.
If time is a constraint, try running the delete process in a background thread, if it is not a problem.
回答2:
Are you doing your tests on device and a Mac, or simulator and Mac.
In the first case the difference is due to the hardware, an iphone is slower than a mac.
In the second case, you should think that is a simulator so the inner mechanism could be different somehow.
What is the difference in sec about the two process?
回答3:
Do not perform long running tasks on main thread. Consider you want to remove all the contents of documents directory.
- (void) deleteDocumentsDirectoryContents
{
NSString *folderPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSError *error = nil;
for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderPath error:&error])
{
[[NSFileManager defaultManager] removeItemAtPath:[folderPath stringByAppendingPathComponent:file] error:&error];
}
}
Call the above function like this.
[self performSelectorInBackground:@selector(deleteDocumentsDirectoryContents) withObject:nil];
来源:https://stackoverflow.com/questions/22100528/performance-of-deleting-folder-with-lots-of-files-on-ios