In Cocoa, is there any way to copy all the files in a directory without copying the directory's subdirectories along with them?
One way would be to copy items in the directory conditionally based on the results of NSFileManagers -fileExistsAtPath:isDirectory::
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *files = [manager contentsOfDirectoryAtPath:pathFrom error:nil];
for (NSString *file in files) {
NSString *fileFrom = [pathFrom stringByAppendingPathComponent:file];
BOOL isDir;
if (![manager fileExistsAtPath:fileFrom isDirectory:&isDir] || isDir) {
continue;
}
NSString *fileTo = [pathTo stringByAppendingPathComponent:file];
NSError *error = nil;
[manager copyItemAtPath:fileFrom toPath:fileTo error:&error];
if (error) // ...
}
Related
I need to raise an Alert panel if a folder does not contain files with the extension strings in code below. The "input" textField contains the path string ... Can't get it to work ... Thanks for help.
NSString * filePath = [input stringValue];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSString *theFolder= [fileURL path];
NSFileManager * fileMan = [[NSFileManager alloc] init];
NSArray * files = [fileMan contentsOfDirectoryAtPath:theFolder error:nil];
if (files)
{
for(int index=0;index<files.count;index++)
{
NSString * file = [files objectAtIndex:index];
if (!([file.pathExtension isEqualToString:#"txt"] || [file.pathExtension isEqualToString:#"rtf"] || [file.pathExtension isEqualToString:#"doc"] || [file.pathExtension isEqualToString:#"rtfd"])) {
///alert code
Replace
NSFileManager * fileMan = [[NSFileManager alloc] init];
with
NSFileManager * fileMan = [[NSFileManager defaultManager];
Make sure that
NSString *theFolder= [fileURL path];
gives you a folder and not a filename!
I would recommend to lowercase all strings in the comparison.
Declare a bool variable outside the for loop like
BOOL otherFiles = NO;
if (files) {
for(int index=0;index<files.count;index++)
{
NSString * file = [files objectAtIndex:index];
if (!([file.pathExtension.lowercaseString isEqualToString:#"txt"] ||
[file.pathExtension.lowercaseString isEqualToString:#"rtf"] ||
[file.pathExtension.lowercaseString isEqualToString:#"doc"] ||
[file.pathExtension.lowercaseString isEqualToString:#"rtfd"])
) otherFiles = YES;
}
if (otherFiles) NSRunAlertPanel.....
Make sure that files contains what you expect!
I need some help with displaying the number of .txt files in a folder.
I can look in a folder for the .txt files:
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSString *theFolder= [fileURL path];
NSError *error;
NSString *file;
NSEnumerator *files = [[[NSFileManager defaultManager]
contentsOfDirectoryAtPath:theFolder error:&error] objectEnumerator];
while(file = [files nextObject] ) {
if( [[file pathExtension] isEqualToString:#"txt"] ) {
... and I can display the total number of files in the folder:
NSArray *filelist= [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:myString error:nil];
NSInteger count = [filelist count];
[totalFiles setIntegerValue:count];
I'm stumped on how to only display the number of .txt files in the given folder.
Thanks for the help.
You could do something like this:
NSEnumerator *files = [[[NSFileManager defaultManager]
contentsOfDirectoryAtPath:theFolder error:&error] objectEnumerator];
NSMutableArray *arrayOfTxtFiles = [[NSMutableArray alloc] init];
while(file = [files nextObject] ) {
if( [[file pathExtension] isEqualToString:#"txt"] ) {
[arrayOfTxtFiles addObject: file];
}
}
NSLog( #"count of .txt files is %d", [arrayOfTxtFiles count] );
arrayOfTxtFiles contains all the .txt filenames.
I'm basing my code off your first code snippet, although there may be an even more elegant way to do what you're trying to do.
I'm writing an OS X application for my personal use where I want to get and subsequently search all files of type plist. I am struggling with the first task. Could you point me in the right direction or provide an online tutorial. Thanks.
NSString *searchDirectory = ...;
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: searchDirectory
error: NULL];
[files enumerateObjectsUsingBlock: ^(NSString *fileName, NSUInteger idx, BOOL *stop) {
if ([[fileName pathExtension] isEqualToString: #"plist"]) {
NSString *filePath = [searchDirectory stringByAppendingPathComponent: fileName];
// Do something with the plist file
}
}];
Try with something like this:
NSError *error = nil;
NSString *folder = <# your folder #>;
NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folder error:&error];
if (error) {
<# deal with error #>
} else {
NSString *path;
for (NSString *entry in contents) {
if ([entry hasSuffix:#"plist"]) {
path = [folder stringByAppendingPathComponent:entry];
<# do something with file at path #>
}
}
}
Also, check related methods in Discovering Directory Contents section in NSFileManager class reference.
I've been trying to write data back to a pre-defined plist file (data.plist) in my bundle. Using the code below I call the routine 'dictionaryFromPlist' to open the file and then call 'writeDictionaryToPlist' to write to the plist file. However, no data gets added to the plist file.
NSDictionary *dict = [self dictionaryFromPlist];
NSString *key = #"Reports";
NSString *value = #"TestingTesting";
[dict setValue:value forKey:key];
[self writeDictionaryToPlist:dict];
- (NSMutableDictionary*)dictionaryFromPlist {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
NSMutableDictionary* propertyListValues = [[NSMutableDictionary alloc]
initWithContentsOfFile:filePath];
return [propertyListValues autorelease];
}
- (BOOL)writeDictionaryToPlist:(NSDictionary*)plistDict{
NSString *filePath = #"data.plist";
BOOL result = [plistDict writeToFile:filePath atomically:YES];
return result;
}
The code runs through successfully and no error is thrown but no data is added to my plist file.
You can not write to your bundle, it is read only. If your case though, you are writing to a relative path, not to the bundle.
I'm not sure what the default working directory is for iOS apps. It is best to use absolute paths. You should be writing to the documents/cache directory. Something like this will get the path for you:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
Then just grab the lastObject and prepend that to your file name.
As mentioned by #logancautrell you can not write in mainbundle, you can save your plist in the app documents folder, you could do so:
NSString *path = #"example.plist";
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count]> 0)? [paths objectAtIndex: 0]: nil;
NSString *documentPath = [basePath stringByAppendingPathComponent:path] // Documents
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL checkfile = [fileManager fileExistsAtPath: documentPath];
NSLog(#"%#", (checkFile ? #"Exist": #"Not exist"));//check if exist
if(!checkfile) {//if not exist
BOOL copyFileToDoc = [yourDictionary writeToFile:documentPath atomically: YES];
NSLog(#"%#",(copyFileToDoc ? #"Copied": #"Not copied"));
}
This code copies the referenced file and places it in the Docs Directory. I'm trying to build a simple backup solution. The problem is this operation does not overwrite the existing file if the operation is repeated.
Two questions:
What's the best way to overwrite in code?
How difficult would it be to append the current date to each copied file? In this case there would be no overwrite operation. This would be much more useful for keeping incremental backups. If I decide to do it this way I understand I would need to create a new path in order to keep things organized.
Thanks.
Paul
NSString * name = #"testFile";
NSArray * files = [NSArray arrayWithObject: name];
NSWorkspace * ws = [NSWorkspace sharedWorkspace];
[ws performFileOperation: NSWorkspaceCopyOperation
source: #"~/Library/Application Support/testApp"
destination: #"~/Documents/"
files: files
tag: 0];
You could try using NSFileManager, example below (untested):
// Better way to get the Application Support Directory, similar method for Documents Directory
- (NSString *)applicationSupportDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
return [basePath stringByAppendingPathComponent:#"testApp"];
}
- (void) removeFile {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *applicationSupportDirectory = [self applicationSupportDirectory];
NSError *error = nil;
NSString* filePath = [applicationSupportDirectory stringByAppendingPathComponent: #"testFile"];
if ([fileManager fileExistsAtPath:filePath isDirectory:NULL]) {
[fileManager removeItemAtPath:filePath error:&error];
}
}
Edit:
Take a look at the NSFileManager Class Reference for other functions that might be useful (for your second question).