0

NSFilemanager is returning true for the following, when there should not be any such file there yet. What is happening?

    if([myManager fileExistsAtPath:[[self documentsDirectory] stringByAppendingPathComponent:@"Music/songlist.txt"]]){

NSLog(@"file is there");

}
RexOnRoids
  • 14,002
  • 33
  • 96
  • 136

3 Answers3

7

The documentation for NSFileManager seems to recommend not checking to see if files exist, and instead just trying to read the file and handle any errors gracefully (e.g. file not found error). What you are describing doesn't sound like a race condition—which is what the documentation's recommendation is trying to circumvent—but what happens if you just try to load the file rather than checking to see if it exists? You could, for example, try the following:

NSError *error;
NSStringEncoding encoding;
NSString *fileContents = [NSString stringWithContentsOfFile:fileName
                                               usedEncoding:&encoding
                                                      error:&error];

if (fileContents == nil)
{
    NSLog (@"%@", error);
}
else
{
    NSLog (@"%@", fileContents);
}

If you get a string with all of the file's contents, then the file is obviously there. If you get an error then something is up with myManager.

dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • 3
    this is a horrible resolution when you consider large files. You don't want to be loading large files into memory just to check if they exist =/ – valheru Jan 22 '13 at 21:10
  • @valheru: You have missed the point of the answer. If you check for a file's existence before trying to read from it, you have introduced a race condition. The best approach is to try reading from the file straight away and if that fails then handle that error appropriately. The example above was only a demonstration of reading a file into a string, but there is a multitude of other more efficient ways to read data from a file using the Foundation framework. Again, as stated in my answer, the above is only an *example*. – dreamlax Jan 22 '13 at 21:14
  • thanks for the clarification. I came across the page because I was looking for a way to check for files existing (without needing to necessarily read from them right away) to show a listing. So in that case, when considering larger files, it would possibly be a performance hog. – valheru Jan 23 '13 at 04:02
  • @valheru: When your program only needs to know about whether a file exists or not (e.g. a lock file or similar) then you are correct, it would be pointless (and potentially bad for performance) to try and read the file if you didn't care about its contents. In these situations `fileExistsAtPath:` is the way to go. – dreamlax Jan 23 '13 at 04:09
  • Yeah and I was running into the same race condition where I delete a file and check too quickly if it exists and it still thinks it exists. I may eventually setup a memory cache of file listings instead or try checking via directory listing or something. – valheru Jan 23 '13 at 05:21
0

Print this out and see if it is what you expect.

NSLog(@"Directory: %@", [[self documentsDirectory] stringByAppendingPathComponent:@"Music/songlist.txt"]];

Also, check that you are defining myManager correctly.

Jordan
  • 21,746
  • 10
  • 51
  • 63
0

This works as expected for me.

 NSFileManager *myManager = [NSFileManager defaultManager];
NSString *documentsDirectory = NSHomeDirectory();

if([myManager fileExistsAtPath:[documentsDirectory stringByAppendingPathComponent:@"Music/songlist.txt"]]){

    NSLog(@"file is there");

}
markhunte
  • 6,805
  • 2
  • 25
  • 44