9

I am new to iPhone programming. I want to read the content of a text file located in a subfolder of the Resource folder.

The Resource folder structure is the following:

Resource

  1. Folder1---->Data.txt
  2. Folder2---->Data.txt
  3. Folder3---->Folder1---->Data.txt

There are multiple files named "Data.txt", so how can I access the files in each folder? I know how to read the text file, but if the Resource structure is similar to the above structure then how can I get the path?

For example, if I want to access the "Data.txt" file from Folder3, how can I get the file path?

Please suggest.

Steph Sharp
  • 11,462
  • 5
  • 44
  • 81
Rupesh
  • 7,866
  • 11
  • 41
  • 58

4 Answers4

16

Your "resource folder" is actually the contents of your main bundle, also know as the application bundle. You use pathForResource:ofType: or pathForResource:ofType:inDirectory: to get the full path for a resource.

Loading the contents of a file as a string is done with the stringWithContentsOfFile:encoding:error: method for an autoreleased string of with initWithContentsOfFile:encoding:error: if you want a retained string.

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Data" 
                                                     ofType:@"txt"
                                                inDirectory:@"Folder1"];
if (filePath != nil) {
  theContents = [NSString stringWithContentsOfFile:filePath
                                          encoding:NSUTF8StringEncoding
                                             error:NULL];
  // Do stuff to theContents
}

This is almost the same answer as given by Shirkrin previously, but with the slight difference that it works on target. This is because initWithContentsOfFile: is deprecated on Mac OS X, and not available at all iPhone OS.

PeyloW
  • 36,742
  • 12
  • 80
  • 99
12

To continue psychotiks answer a full example would look like this:

NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];
NSString *filePath = nil;

if (filePath = [thisBundle pathForResource:@"Data" ofType:@"txt" inDirectory:@"Folder1"])  {

    theContents = [[NSString alloc] initWithContentsOfFile:filePath];

    // when completed, it is the developer's responsibility to release theContents

}

Notice that you can use -pathForResource:ofType:inDirectory to access ressources in sub directories.

Shirkrin
  • 3,993
  • 1
  • 29
  • 35
  • But there are multiple Folder with same Name in different folder. so in this case how can achieve the path – Rupesh Sep 30 '09 at 08:32
  • 4
    @Rupesh: For the second folder you would need to use: `[thisBundle pathForResource:@"Data" ofType:@"txt" inDirectory:@"Folder3/Folder1"]`. Notice that `inDirectory:` argument is relative to the bundle root. – PeyloW Sep 30 '09 at 08:53
  • 1
    You should really use `[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL]`, this way the memory is _"managed"_, and more importantly `initWithContentsOfFile:` is deprecated since Mac OS X 10.4, and **not available on iPhone OS**. So the code will only work in simulator. – PeyloW Sep 30 '09 at 08:58
  • @Peylow - I agree with you. The example is a modified version from the NSBundle documentation which does not use autorelase pools. – Shirkrin Sep 30 '09 at 09:36
  • 1
    @PeyloW - While initWithContentsOfURL is indeed deprecated, Apple did so merely to require you to specify an encoding (wise move on their part). So the method initWithContentsOfURL:encoding:error: is available in iOS 2.0 and later (at least through iOS 5.1). – Basil Bourque Oct 20 '12 at 01:12
  • What if I want to retrieve all files in the folder, this doesn't seem to work.... NSString *inWorkPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"In-Work"]; NSArray *resContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:inWorkPath error:&error]; – Eshwar Chaitanya Dec 24 '14 at 19:12
8

Shirkrin's answer and PeyloW's answer above were both useful, and I managed to use pathForResource:ofType:inDirectory: to access files with the same name in different folders in my app bundle.

I also found an alternative solution here that suited my requirements slightly better, so I thought I'd share it. In particular, see this link.

For example, say I have the following Folder References (blue icons, Groups are yellow):

enter image description here

Then I can access the image files like this:

NSString * filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"pin_images/1/2.jpg"];
UIImage * image = [UIImage imageWithContentsOfFile:filePath];

As a side note, the pathForResource:ofType:inDirectory: equivalent looks like this:

NSString * filePath = [[NSBundle mainBundle] pathForResource:@"2" ofType:@"jpg" inDirectory:@"pin_images/1/"];
Community
  • 1
  • 1
Steph Sharp
  • 11,462
  • 5
  • 44
  • 81
4
    NSBundle* bundle = [NSBundle mainBundle];
    NSString* path = [bundle bundlePath];

This gives you the path to your bundle. From there on, you can navigate your folder structure.

psychotik
  • 38,153
  • 34
  • 100
  • 135