As we saw, it is very easy to save/read a string to/from a file. GNUstep goes well beyond this. You can save/read any object to/from a file, using the archiving/dearchiving facilities; these facilities are great, but save/read objects in a binary format. For arrays and dictionaries containing only strings, GNUstep provides other facilities (the ones we are interested on here) to save/read them from files in a human-readable (and human-modifiable) format, called a property list. Actually, the set of objects which you can save and read in this way is much more general:
To save or read a dictionary or an array of the correct type, you write or read them to/from file in the same way as you do with strings, that is, you use the method -writeToFile:atomically: to write them to files, and the method +dictionaryWithContentsOfFile: (for dictionaries) or the method +arrayWithContentsOfFile: (for arrays) to read them from files.
For example, the following code creates a dictionary which is used to store, for each person, some info; then it saves it to a file in the form of a property list:
#include <Foundation/Foundation.h> int main (void) { NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSMutableDictionary *dict; NSDictionary *dict2; dict = [NSMutableDictionary new]; AUTORELEASE (dict); dict2 = [NSDictionary dictionaryWithObjectsAndKeys: @"Nicola", @"Name", @"Pero", @"Surname", @"n.pero@mi.flashnet.it", @"Email", nil]; [dict setObject: dict2 forKey: @"Nicola"]; dict2 = [NSDictionary dictionaryWithObjectsAndKeys: @"Ettore", @"Name", @"Perazzoli", @"Surname", @"ettore@helixcode.com", @"Email", nil]; [dict setObject: dict2 forKey: @"Ettore"]; dict2 = [NSDictionary dictionaryWithObjectsAndKeys: @"Richard", @"Name", @"Frith-Macdonald", @"Surname", @"richard@brainstorm.co.uk", @"Email", nil]; [dict setObject: dict2 forKey: @"Richard"]; if ([dict writeToFile: @"/home/nico/testing" atomically: YES]) { NSLog (@"Success"); } else { NSLog (@"Failure"); } return 0; }I tried it on my machine (I encourage you to do the same on yours) and it wrote the following into my /home/nico/testing file:
{ Ettore = { Email = "ettore@helixcode.com"; Name = Ettore; Surname = Perazzoli; }; Nicola = { Email = "n.pero@mi.flashnet.it"; Name = Nicola; Surname = Pero; }; Richard = { Email = "richard@brainstorm.co.uk"; Name = Richard; Surname = "Frith-Macdonald"; }; }As you see, it is a very simple format, and very nice to read and edit manually. The " (speech-marks) are used whenever a string contains spaces or special characters; they are omitted for simple strings. Dictionaries are saved as in
{ Email = "richard@brainstorm.co.uk"; Name = Richard; Surname = "Frith-Macdonald"; }(Note that they use curly brackets, and each key/value pairs is followed by a ; (semicolon), even the last one). Arrays (not shown in the previous example) are saved as in
( "Nicola Pero", "Ettore Perazzoli", "Richard Frith-Macdonald" )(they use round brackets, and each entry is followed by a comma, except the last one). You can find other examples of this format by looking inside your /GNUstep directory.
One of the advantages of this format is that it is very general, but still very portable and simple. It is so easy and simple (unless XML) that you can write a complete parser/unparser for a new platform in one or two days.
Once you have saved the data to a file in the form of a property list, you can easily retrieve it from the same file. The following code retrieves the data from the file /home/nico/testing, and prints out the Email of Ettore:
#include <Foundation/Foundation.h> int main (void) { NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSDictionary *dict; NSDictionary *dict2; NSString *email; dict = [NSDictionary dictionaryWithContentsOfFile: @"/home/nico/testing"]; dict2 = [dict objectForKey: @"Ettore"]; email = [dict2 objectForKey: @"Email"]; NSLog (@"Ettore's Email is: %@", email); return 0; }