Check if file name exists in document directory - iphone

In my application I am using the following code to save images/files into the application’s document directory:
-(void)saveImageDetailsToAppBundle{
NSData *imageData = UIImagePNGRepresentation(userSavedImage); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png",txtImageName.text]]; //add our image to the path
NSLog(fullPath);
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the image
NSLog(#"image saved");
}
However, there is a problem with the image name. If a file exists in the documents directory, the new file with the same name will overwrite the old file. How can I check if the file name exists in the documents directory?

Use NSFileManager's fileExistsAtPath: method to check if it exists or not.
usage
if ( ![fileManager fileExistsAtPath:filePath] ) {
/* File doesn't exist. Save the image at the path */
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil];
} else {
/* File exists at path. Resolve and save */
}

if ([[NSFileManager defaultManager] fileExistsAtPath:myFilePath])

NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:#"file name"];
if([fileManager fileExistsAtPath:writablePath]){
// file exist
}
else{
// file doesn't exist
}

As Apple Documentation says it is better to perform some action and then handle no file existance than checking if file is existing.
Note: Attempting to predicate behavior based on the current state of the file system or a particular file on the file system is not recommended. Doing so can cause odd behavior or race conditions. It's far better to attempt an operation (such as loading a file or creating a directory), check for errors, and handle those errors gracefully than it is to try to figure out ahead of time whether the operation will succeed. For more information on file system race conditions, see “Race Conditions and Secure File Operations” in Secure Coding Guide.

Related

How to check if folder is empty, and instantiate file names inside the folder into NSStrings? (iphone cocoa)

Just wondering, how would I check if a particular folder is holding files, and instantiate file names inside the folder into NSStrings? I know of a class called NSFileManager, but I'm not sure how to apply it to suit my objective.
NSArray * files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderLocationString error:nil];
By default all your custom files and data will be stored in the documents directory in your app. I've put a sample code below to access the default document directory; plus a custom folder you may have in there called 'MyFolderName'
The end result will be an array which has a list of NSString objects of the files or directories in the path you have specified.
//Accessing the default documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//Appending the name of your custom folder, if you have any
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"MyFolderName"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:path]) { // Directory exists
NSArray *listOfFiles = [fileManager contentsOfDirectoryAtPath:path error:nil];
}
Hope this helps! :)

How can I save a file into appbundle

I have an image named my-image. Can I save this image to the application bundle? If yes, can you provide me the code or paths.
As of now, I have the following code –
NSData * imageData = UIImagePNGRepresentation(userSavedImage); //convert image into .png format.
NSFileManager * fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString * documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString * fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png",txtImageName.text]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the image
NSLog(#"image saved");
However it is saving in
/Users/tsplmac01/Library/Application Support/iPhone Simulator/4.3/Applications/BC5DE1D8-B875-44BC-AC74-04A17329F29A/.
& not in the application bundle. Please tell me how I can do it.
The app bundle is read only for the app, so it is not possible to write to it.
This is a good restriction, because it would otherwise be wiped out when the app gets updated. You may want to write to the documents directory instead.

Saving NSMutableArray to iPhone device

In the Simulator I can save an NSMutableArray to a file and read it back with the following code:
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:#"RiskValues"]){ // If file exists open into table
NSLog(#"Risk Values File Exists");
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:#"RiskValues", documentsDirectory];
gRiskValues = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
gRiskValuesAlreadyInitialised = YES;
} else {
NSLog(#"Can't find RiskValues file, so initialising gRiskValues table");
Do something else .......
}
This doesn't work on the device. I have tried to locate the file using the following but it still doesn't work:
NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent#"RiskValues"];
What am I doing wrong?
Great answers from everyone. I have resolved the file path and existence issues at a stroke. Many, many thanks.
You have to provide absolute path here:
if ([fileManager fileExistsAtPath:#"RiskValues"])
So it must look like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent:#"RiskValues"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath: fullFileName]){ // If file exists open into table
NSLog(#"Risk Values File Exists");
gRiskValues = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
gRiskValuesAlreadyInitialised = YES;
} else {
NSLog(#"Can't find RiskValues file, so initialising gRiskValues table");
Do something else .......
}
NSString *fullFileName = [NSString stringWithFormat:#"RiskValues", documentsDirectory];
this line, you're not creating your full path string right. what you should do is
NSString *fullFileName = [documentsDirectory stringByAppendingPathComponent:#"RiskValues"];
also this check
if ([fileManager fileExistsAtPath:#"RiskValues"])
Will never pass on iOS as it is not a full path to any place you are allowed to write at in your sandbox. I suppose it works on the simulator because on the mac it's looking up relatively to the HD root (or something, not sure how the mac file system works :) ), but on the iOS you're going to have to give it a path to a file/directory in your documents (maybe by appending #"RiskValues" to it or whatever)
1) [NSString stringWithFormat:#"RiskValues", documentsDirectory] is just #"RiskValues". So this name points to file in application's directory.
2) [fileManager fileExistsAtPath:#"RiskValues"] searches for file in application directory. It's available for read/write in simulator (it's in your computer file system after all) but it's read-only on device.
BTW (NSFileManager Class Reference)
Attempting to predicate behavior based
on the current state of the file
system or a particular file on the
file system is not recommended. Doing
so can cause odd behavior in the case
of file system race conditions. It's
far better to attempt an operation
(such as loading a file or creating a
directory), check for errors, and
handle any error gracefully than it is
to try to figure out ahead of time
whether the operation will succeed.
Solution:
1) Do not check file presence. Just try to make dictionary with initWithContentsOfFile:encoding:error:
2) You want it to be in documents directory so construct path like this
[documentsDirectory stringByAppendingPathComponent:#"RiskValues"];

download and save image to root

How would i download and save an image to the root of the application so basically i can access the image via
[UIImage imageNamed:#"myimage.jpg"];
Thanks
Mason
First you need to get the Image Data
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://media03.linkedin.com/mpr/mpr/shrink_80_80/p/3/000/064/2e2/1bd3849.jpg"]];
Then you need to write the data to Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathLD = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"imageLD%d.jpeg",[[NSDate date] timeIntervalSince1970]]];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: pathLD]){
[imageData writeToFile:pathLD atomically:YES];
} else {
NSLog(#"File exists at path:%#", pathLD);
}
To get the image from Documents you do:
[UIImage imageWithContentsOfFile:pathLD];
Good luck :D;
You shouldn't for various reasons. Consider your application directory as being read-only.
You should use the Documents or Library directory. Apple recommends that you should use the Documents directory if your files should be user-accessible via iTunes (if you have enabled the file sharing via iTunes), or use a custom subdirectory of Library (which you need to create with NSFileManager) if it shouldn't be user-visible (but should be backed up).
You can query the path to the Library directory like this:
NSArray *paths;
paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
NSUserDomainMask, YES);
// dir = [paths objectAtIndex:0];
Substitute NSLibraryDirectory with NSDocumentsDirectory to get the Documents directory.
Then you would make a method that returns the full path to your image, and you would then do:
[UIImage imageWithContentsOfFile:[self pathForImage:#"myimage.jpg"]]

Check if file exist or not?

i am new to iPhone programming.
What is the proper way to check that whether a file is exist or not?
BOOL isDirectory = NO;
if ( [[NSFileManager defaultManager]
fileExistsAtPath:path
isDirectory: &isDirectory ]) {
// file already exists
} else {
// file does not yet exist
}
To put it in more detail:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if ([[NSFileManager defaultManager] fileExistsAtPath:documentsDirectory]){
//Do something...
}
You can append the actual file name to "documentsDirectory" like this: [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.jpg", spidermanpic]].
The isDirectory option in the answer above is used to check if the path is a directory or a file. Please keep in mind that it is a pointer. It wont work without the "&".