27.02.2011
Verwendung von Dateipfaden bei Objective-C
Im Folgenden wird an ein paar Beispielen erklärt, mit welchen Hilfsmethoden einfach mit Dateipfaden umgegangen werden kann. Beispielsweise das Zerlegen von Pfaden, Zugriff auf das Parent-Verzeichnis, Inhalt eines Verzeichnisses, usw.
Zerlegen von Dateipfaden
Man ist oft in der Situation einen Dateipfad in seine Bestandteile zu zerlegen. Beispielsweise, um aus den Bestandteilen einen neuen leicht veränderten Pfad zusammenzubauen. Wenn man aus der Java-Welt kommt, denkt man zuerst an java.io.File
oder java.util.StringTokenizer
. Dort wird man bei Objective-C allerdings nicht fündig. Die gesuchten Methoden befinden sind in der Klasse NSString
. Dort existiert eine Methode pathComponents
, die einen Dateipfad in seine Bestandteile zerlegt und ein NSArray
zurückliefert.
Um den Dateipfad /Library/Fonts
zu zerlegen, kann der folgende Quellcode verwendet werden:
NSString *path = @"/Library/Fonts"; NSArray * components = [path pathComponents]; for(id c in components) { NSLog(@"%@", c); }
Als Ausgabe erhält man folgendes:
2011-02-27 08:31:04.886 FileHandling[14855:a0f] / 2011-02-27 08:31:04.889 FileHandling[14855:a0f] Library 2011-02-27 08:31:04.890 FileHandling[14855:a0f] Fonts
Existenzprüfung von Dateien
Wenn eine Datei geladen werden soll, ist es sinnvoll, vorher zu überprüfen, ob sie vorhanden ist. Dazu bietet die Klasse NSFileManager
die Methode fileExistsAtPath:
. Die Methode bekommt als Parameter einen Pfad als String übergeben.
In dem folgenden Beispiel soll überprüft werden, ob eine bestimmte Schriftart im Fonts-Ordner abgelegt ist.
NSString *filePath = @"/Library/Fonts/Arial Bold.ttf"; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL fileExists = [fileManager fileExistsAtPath:filePath]; NSLog(@"File exists: %i", fileExists);
In dem Beispiel sollte als Ausgabe der Wert 1
erscheinen, weil die Datei in dem angegebenen Verzeichnis existiert.
Bestimmung des absoluten Dateipfads
In dem Beispiel Existenzprüfung von Dateien ist davon ausgegangen worden, daß der Dateipfad vollständig bekannt ist. Leider ist das nicht immer so. Oft kennt man den absoluten Dateipfad, der für die Überprüfung notwendig ist, nicht. Wenn dann versucht wird den Pfad mit Hilfe des Finders zu bestimmen, wird es auch Probleme geben, weil Teile des Pfads von Mac OSX lokalisiert wurden. Eine naheliegene Lösung ist, die Datei per Drag&Drop in Xcode zu ziehen. Damit erhält man einen Pfad in der Form file://localhost/Users/joern/Documents/22.02.11 18-42-05.tcx
. Leider läßt sich die Existenzprüfung einer Datei auch damit nicht durchführen. Ein weiterer Ansatz ist den vorderen Teil des Pfad wegzulassen und einen relativen Pfad anzugeben. Beispielsweise in der Form ~/Documents/22.02.11 18-42-05.tcx
. Dies funktioniert allerdings auch nicht. Glücklicherweise stellt die Klasse NSString
die Methode stringByResolvingSymlinksInPath
zur Verfügung. Mit dieser Methode lassen sich die symbolischen Links innerhalb eines Pfades auflösen. Beispielsweise wird aus dem Pfad ~/Documents/22.02.11 18-42-05.tcx
der Dateipfad /Users/joern/Documents/22.02.11 18-42-05.tcx
.
Hinweis
Das Zeichen ~ (Tilde) erhält man, indem alt-N auf der Tastatur gedrückt wird.
In dem folgenden Beispiel wird überprüft, ob sich die Datei 22.02.11 18-42-05.tcx
im Verzeichnis Dokumente befindet. Die erste auskommentierte Zeile ist durch Drag&Drop aus dem Finder entstanden. Die zweite auskommentierte Zeile ist der relative Pfad zu der Datei. Beide Lösungen funktionieren nicht. Erst das Auflösen der symbolischen Links mit der Methode stringByResolvingSymlinksInPath
bringt das gewünschte Ergebnis.
//NSString *filePath = @"file://localhost/Users/heike/Documents/22.02.11 18-42-05.tcx"; //Does not work! //NSString *filePath = @"~/Documents/22.02.11 18-42-05.tcx"; // Does not work! NSString *filePath = [@"~/Documents/22.02.11 18-42-05.tcx" stringByResolvingSymlinksInPath]; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL fileExists = [fileManager fileExistsAtPath:filePath]; NSLog(@"File %@ exists: %i", filePath, fileExists);
Die Ausgabe sieht dann ungefähr so aus:
2011-02-27 09:34:02.739 FileHandling[15211:a0f] File /Users/joern/Documents/22.02.11 18-42-05.tcx exists: 1
Zugriff auf das Parent-Verzeichnis
Oft tritt der Fall ein, daß man einen vollständigen Pfad zu einer Datei hat, aber nur das Verzeichnis in der sich die Datei befindet für das weitere arbeiten benötigt. Dafür stellt Objective-C die Methode stringByDeletingLastPathComponent:
zur Verfügung.
Ausgehend von dem Beispiel in Bestimmung des absoluten Dateipfads wird der Dateipfad filePath
um die letzte Pfadkomponente verkürzt.
NSString *filePath = [@"~/Documents/22.02.11 18-42-05.tcx" stringByResolvingSymlinksInPath]; NSString* parentPath = [filePath stringByDeletingLastPathComponent]; NSLog(@"Parent path: %@", parentPath);
Als Ausgabe erhält man folgendes
Parent path: /Users/joern/Documents
Ausgabe aller Dateien eines Verzeichnisses
Oft sollen alle Dateien eines Verzeichnisses verarbeitet werden. Beispielweise möchte man alle Dateien im Verzeichnis Dokumente auf der Konsole ausgeben. Der folgende Quellcode tut genau dies. Mit Hilfe der Methode contentsOfDirectoryAtPath
des NSFileManager
werden alle Dateien in dem Verzeichnis aufgelistet.
NSError *error = nil; NSString *path = [@"~/Documents/" stringByResolvingSymlinksInPath]; NSFileManager *manager = [NSFileManager defaultManager]; NSArray *directoryContent = [manager contentsOfDirectoryAtPath:path error:&error]; for(id file in directoryContent) { NSLog(@"%@", file); }
Dateipfade zusammenbauen
Eine weitere sehr nützliche Methode der Klasse NSString
ist stringByAppendingPathComponent:
. Mit ihr lassen sich Dateipfade zusammenbauen. Hat man beispielsweise einen Pfad path
, der auf das Dokumente-Verzeichnis zeigt und man weiß, daß sich in dem Verzeichnis die Datei test.txt
befindet, dann kann man den Pfad mit Hilfe der Methode stringByAppendingPathComponent
um test.txt
ergänzen. Vorteil diese Vorgehensweise ist, daß man sich nicht um die Trennzeichen (Slash, Backslash) kümmern muß.
NSString *path = [@"~/Documents/" stringByResolvingSymlinksInPath]; NSString *subpath = [path stringByAppendingPathComponent:@"test.txt"]; NSLog(@"Subpath: %@", subpath);