Wie überprüfe ich, ob eine Datei im Ordner "Dokumente" vorhanden ist?

216

Ich habe eine Anwendung mit In-App-Kauf, bei der der Benutzer beim Kauf einer HTML-Datei eine HTML-Datei in den Ordner "Dokumente" meiner App herunterlädt.

Jetzt muss ich überprüfen, ob diese HTML-Datei vorhanden ist. Wenn dies der Fall ist, laden Sie diese HTML-Datei, andernfalls laden Sie meine Standard-HTML-Seite.

Wie kann ich das machen? Mit NSFileManagerkann ich nicht raus mainBundle..

Obliviux
quelle
"Mit NSFileManager komme ich nicht aus mainBundle heraus" - woher haben Sie diese Fehlinformationen?

Antworten:

521

Swift 3:

let documentsURL = try! FileManager().url(for: .documentDirectory,
                                          in: .userDomainMask,
                                          appropriateFor: nil,
                                          create: true)

... gibt Ihnen eine Datei-URL des Dokumentenverzeichnisses. Im Folgenden wird überprüft, ob eine Datei mit dem Namen foo.html vorhanden ist:

let fooURL = documentsURL.appendingPathComponent("foo.html")
let fileExists = FileManager().fileExists(atPath: fooURL.path)

Ziel c:

NSString* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];

NSString* foofile = [documentsPath stringByAppendingPathComponent:@"foo.html"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
Nikolai Ruhe
quelle
12
Beachten Sie, dass Sie eine Datei aus dem persönlichen Dokumentenverzeichnis Ihrer Anwendung laden, nicht aus dem globalen, das Sie finden, wenn Sie einen Jailbreak haben. Wenn Sie Ihre Anwendung in / Applications so installieren, als wäre es eine Hauptanwendung, haben Sie Zugriff auf das gesamte Dateisystem und verwenden das Verzeichnis für freigegebene Dokumente. Wenn Sie es über iTunes oder XCode installieren, verwenden Sie das persönliche Verzeichnis Ihrer Anwendungen. Es ist schön, Dateien zu Sicherungszwecken in Ihrem lokalen Verzeichnis zu speichern.
Epsilon Prime
6
objectAtIndex: 0 kann jetzt durch firstObject
Govind
3
Oder einfach [0]über den
temporärer_Benutzername
firstObject ist sicherer als [0] und objectAtIndex: 0
Itachi
1
@Itachi Eigentlich bevorzuge ich in diesem Fall die Ausnahme, wenn sich kein Objekt im Array befindet. Wenn das Ergebnis firstObjectist, nilgibt es keinen vernünftigen Weg, wie das Programm fortgesetzt werden könnte, da etwas in den Apple-Frameworks ernsthaft kaputt ist.
Nikolai Ruhe
14

Apple rät davon ab, sich auf die fileExistAtPath: -Methode zu verlassen. Es ist oft besser, einfach zu versuchen, eine Datei zu öffnen und den Fehler zu beheben, wenn die Datei nicht vorhanden ist.

NSFileManager-Klassenreferenz

Hinweis: Es wird nicht empfohlen, das Verhalten anhand des aktuellen Status des Dateisystems oder einer bestimmten Datei im Dateisystem vorherzusagen. Dies kann zu ungewöhnlichem Verhalten oder Rennbedingungen führen. Es ist weitaus besser, einen Vorgang zu versuchen (z. B. eine Datei zu laden oder ein Verzeichnis zu erstellen), auf Fehler zu prüfen und diese Fehler ordnungsgemäß zu behandeln, als im Voraus herauszufinden, ob der Vorgang erfolgreich sein wird. Weitere Informationen zu den Race-Bedingungen des Dateisystems finden Sie unter „Race-Bedingungen und sichere Dateivorgänge“ im Secure Coding Guide.

Quelle: Apple Developer API-Referenz

Aus der sicheren Codierungsanleitung.

Um dies zu verhindern, überprüfen Programme häufig, ob eine temporäre Datei mit einem bestimmten Namen noch nicht im Zielverzeichnis vorhanden ist. Wenn eine solche Datei vorhanden ist, löscht die Anwendung sie oder wählt einen neuen Namen für die temporäre Datei, um Konflikte zu vermeiden. Wenn die Datei nicht vorhanden ist, öffnet die Anwendung die Datei zum Schreiben, da die Systemroutine, die eine Datei zum Schreiben öffnet, automatisch eine neue Datei erstellt, wenn keine vorhanden ist. Ein Angreifer kann durch kontinuierliches Ausführen eines Programms, das eine neue temporäre Datei mit dem entsprechenden Namen erstellt, (mit ein wenig Beharrlichkeit und etwas Glück) die Datei in der Lücke zwischen der Überprüfung durch die Anwendung erstellen, um sicherzustellen, dass die temporäre Datei nicht vorhanden ist und wenn es zum Schreiben geöffnet wird. Die Anwendung öffnet dann die Datei des Angreifers und schreibt in sie (denken Sie daran, dass die Systemroutine eine vorhandene Datei öffnet, falls vorhanden). und erstellt eine neue Datei nur, wenn keine Datei vorhanden ist). Die Datei des Angreifers verfügt möglicherweise über andere Zugriffsberechtigungen als die temporäre Datei der Anwendung, sodass der Angreifer den Inhalt lesen kann. Alternativ kann der Angreifer die Datei bereits geöffnet haben. Der Angreifer kann die Datei durch einen festen Link oder einen symbolischen Link zu einer anderen Datei ersetzen (entweder einer, die dem Angreifer gehört, oder einer vorhandenen Systemdatei). Beispielsweise könnte der Angreifer die Datei durch einen symbolischen Link zur Systemkennwortdatei ersetzen, sodass die Systemkennwörter nach dem Angriff so stark beschädigt wurden, dass sich niemand, einschließlich des Systemadministrators, anmelden kann. Alternativ kann der Angreifer die Datei bereits geöffnet haben. Der Angreifer kann die Datei durch einen festen Link oder einen symbolischen Link zu einer anderen Datei ersetzen (entweder einer, die dem Angreifer gehört, oder einer vorhandenen Systemdatei). Beispielsweise könnte der Angreifer die Datei durch einen symbolischen Link zur Systemkennwortdatei ersetzen, sodass die Systemkennwörter nach dem Angriff so stark beschädigt wurden, dass sich niemand, einschließlich des Systemadministrators, anmelden kann. Alternativ kann der Angreifer die Datei bereits geöffnet haben. Der Angreifer kann die Datei durch einen festen Link oder einen symbolischen Link zu einer anderen Datei ersetzen (entweder einer, die dem Angreifer gehört, oder einer vorhandenen Systemdatei). Beispielsweise könnte der Angreifer die Datei durch einen symbolischen Link zur Systemkennwortdatei ersetzen, sodass die Systemkennwörter nach dem Angriff so stark beschädigt wurden, dass sich niemand, einschließlich des Systemadministrators, anmelden kann.

Orkoden
quelle
1
Dies ist zwar eine gute Antwort für sich und bietet großartige Ratschläge. Es wäre gut zu sehen, wie dies mit einem kleinen Codebeispiel implementiert werden könnte.
SnareChops
8

Wenn Sie Ihr Dateisystem anders einrichten oder nach einer anderen Möglichkeit suchen, ein Dateisystem einzurichten und dann zu überprüfen, ob eine Datei im Dokumentenordner vorhanden ist, finden Sie hier ein weiteres Beispiel. zeigen auch dynamische Prüfung

for (int i = 0; i < numberHere; ++i){
    NSFileManager* fileMgr = [NSFileManager defaultManager];
    NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString* imageName = [NSString stringWithFormat:@"image-%@.png", i];
    NSString* currentFile = [documentsDirectory stringByAppendingPathComponent:imageName];
    BOOL fileExists = [fileMgr fileExistsAtPath:currentFile];
    if (fileExists == NO){
        cout << "DOESNT Exist!" << endl;
    } else {
        cout << "DOES Exist!" << endl;
    }
}
John Riselvato
quelle
4

Swift 2.0

So überprüfen Sie mit Swift, ob die Datei vorhanden ist

func isFileExistsInDirectory() -> Bool {
    let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
    let documentsDirectory: AnyObject = paths[0]
    let dataPath = documentsDirectory.stringByAppendingPathComponent("/YourFileName")

    return NSFileManager.defaultManager().fileExistsAtPath(dataPath)
}
Tal Zion
quelle
3

Überprüfen Sie, ob eine Datei neben dem Dokument- / Catchimage-Pfad vorhanden ist:

NSString *stringPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *tempName = [NSString stringWithFormat:@"%@/catchimage/%@.png",stringPath,@"file name"];
NSLog(@"%@",temName);
if([[NSFileManager defaultManager] fileExistsAtPath:temName]){
    // ur code here
} else {
    // ur code here** 
}
Mani
quelle
0
NSArray *directoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *imagePath =  [directoryPath objectAtIndex:0];
//If you have superate folder
imagePath= [imagePath stringByAppendingPathComponent:@"ImagesFolder"];//Get docs dir path with folder name
_imageName = [_imageName stringByAppendingString:@".jpg"];//Assign image name
imagePath= [imagePath stringByAppendingPathComponent:_imageName];
NSLog(@"%@", imagePath);

//Method 1:
BOOL file = [[NSFileManager defaultManager] fileExistsAtPath: imagePath];
if (file == NO){
    NSLog("File not exist");
} else {
    NSLog("File exist");
}

//Method 2:
NSData *data = [NSData dataWithContentsOfFile:imagePath];
UIImage *image = [UIImage imageWithData:data];
if (!(image == nil)) {//Check image exist or not
    cell.photoImageView.image = image;//Display image
}
iOS
quelle
0

NSURL.h vorgesehen , - (BOOL)checkResourceIsReachableAndReturnError:(NSError **)errordies zu tun

NSURL *fileURL = [NSURL fileURLWithPath:NSHomeDirectory()];
NSError * __autoreleasing error = nil;
if ([fileURL checkResourceIsReachableAndReturnError:&error]) {
    NSLog(@"%@ exists", fileURL);
} else {
    NSLog(@"%@ existence checking error: %@", fileURL, error);
}

Oder mit Swift

if let url = URL(fileURLWithPath: NSHomeDirectory()) {
    do {
        let result = try url.checkResourceIsReachable()
    } catch {
        print(error)
    }
}
DawnSong
quelle