Come verificare se esiste un file nella cartella Documenti?


216

Ho un'applicazione con In-App Purchase, che quando l'utente acquista qualcosa, scarica un file html nella cartella Documenti della mia app.

Ora devo verificare se questo file HTML esiste, quindi se vero, carica questo file HTML, altrimenti carica la mia pagina HTML predefinita.

Come posso farlo? Con NSFileManagernon riesco ad uscire da mainBundle..


"Con NSFileManager non riesco ad uscire da mainBundle" - da dove hai preso questo pezzo di disinformazione?

Risposte:


521

Swift 3:

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

... ti dà un URL del file della directory dei documenti. Il seguente controlla se esiste un file chiamato foo.html:

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

Objective-C:

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

NSString* foofile = [documentsPath stringByAppendingPathComponent:@"foo.html"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];

12
Si noti che si sta caricando un file dalla directory Documenti personali dell'applicazione, non quella globale che si trova se si esegue il jailbreak. Se installi la tua applicazione in / Applicazioni come se fosse un'applicazione principale, avrai accesso all'intero file system e utilizzerai la directory Documenti condivisa. Se lo installi tramite iTunes o XCode, utilizzerai la directory personale delle tue applicazioni. È bello archiviare i file nella directory locale a scopo di backup.
Epsilon Prime,

6
objectAtIndex: 0 ora può essere sostituito con firstObject
Govind

3
O semplicemente [0]tramite indice di accesso
temporary_user_name

firstObject è più sicuro di [0] e objectAtIndex: 0
Itachi,

1
@Itachi In realtà in questo caso preferisco l'eccezione quando non ci sono oggetti nell'array. Se il risultato firstObjectè che nilnon esiste un modo ragionevole per continuare il programma, poiché qualcosa nei framework di Apple è seriamente rotto.
Nikolai Ruhe,

14

Apple consiglia di non fare affidamento sul metodo fileExistAtPath: Spesso è meglio provare ad aprire un file e gestire l'errore se il file non esiste.

Riferimento classe NSFileManager

Nota: non è consigliabile tentare di prevedere il comportamento in base allo stato corrente del file system o a un determinato file sul file system. Ciò potrebbe causare comportamenti strani o condizioni di gara. È molto meglio tentare un'operazione (come caricare un file o creare una directory), verificare la presenza di errori e gestirli con grazia piuttosto che cercare di capire in anticipo se l'operazione avrà esito positivo. Per ulteriori informazioni sulle condizioni di gara del file system, consultare "Condizioni di gara e operazioni sui file protetti" nella Guida alla codifica sicura.

Fonte: riferimento API per sviluppatori Apple

Dalla guida alla codifica sicura.

Per evitare ciò, i programmi spesso controllano che un file temporaneo con un nome specifico non esista già nella directory di destinazione. Se esiste un file simile, l'applicazione lo elimina o sceglie un nuovo nome per il file temporaneo per evitare conflitti. Se il file non esiste, l'applicazione apre il file per la scrittura, poiché la routine di sistema che apre un file per la scrittura crea automaticamente un nuovo file se non esiste. Un utente malintenzionato, eseguendo continuamente un programma che crea un nuovo file temporaneo con il nome appropriato, può (con un po 'di persistenza e un po' di fortuna) creare il file nel divario tra quando l'applicazione ha verificato per assicurarsi che il file temporaneo non esistesse e quando lo apre per la scrittura. L'applicazione quindi apre il file dell'attaccante e lo scrive (ricorda, la routine di sistema apre un file esistente se ce n'è uno, e crea un nuovo file solo se non esiste alcun file esistente). Il file dell'aggressore potrebbe avere autorizzazioni di accesso diverse rispetto al file temporaneo dell'applicazione, quindi l'attaccante può quindi leggere il contenuto. In alternativa, l'attaccante potrebbe avere il file già aperto. L'autore dell'attacco potrebbe sostituire il file con un collegamento reale o simbolico a un altro file (uno di proprietà dell'attaccante o un file di sistema esistente). Ad esempio, l'utente malintenzionato potrebbe sostituire il file con un collegamento simbolico al file delle password di sistema, in modo che dopo l'attacco le password di sistema siano state corrotte al punto che nessuno, incluso l'amministratore di sistema, possa accedere. In alternativa, l'attaccante potrebbe avere il file già aperto. L'autore dell'attacco potrebbe sostituire il file con un collegamento reale o simbolico a un altro file (uno di proprietà dell'attaccante o un file di sistema esistente). Ad esempio, l'utente malintenzionato potrebbe sostituire il file con un collegamento simbolico al file delle password di sistema, in modo che dopo l'attacco le password di sistema siano state corrotte al punto che nessuno, incluso l'amministratore di sistema, possa accedere. In alternativa, l'attaccante potrebbe avere il file già aperto. L'autore dell'attacco potrebbe sostituire il file con un collegamento reale o simbolico a un altro file (uno di proprietà dell'attaccante o un file di sistema esistente). Ad esempio, l'utente malintenzionato potrebbe sostituire il file con un collegamento simbolico al file delle password di sistema, in modo che dopo l'attacco le password di sistema siano state corrotte al punto che nessuno, incluso l'amministratore di sistema, possa accedere.


1
Sebbene questa sia una buona risposta da sola, fornisce ottimi consigli. Sarebbe bello vedere come questo potrebbe essere implementato con un piccolo esempio di codice.
SnareChops

8

Se si imposta il file system in modo diverso o si cerca un modo diverso di impostare un file system e quindi verificare se esiste un file nella cartella documenti, ecco un altro esempio. mostra anche il controllo dinamico

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;
    }
}

4

Swift 2.0

Ecco come verificare se il file esiste usando Swift

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)
}

3

controlla se il file esiste nel lato del percorso documento / catchimage:

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** 
}

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
}

0

NSURL.h ha provveduto - (BOOL)checkResourceIsReachableAndReturnError:(NSError **)errora farlo

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

O usando Swift

if let url = URL(fileURLWithPath: NSHomeDirectory()) {
    do {
        let result = try url.checkResourceIsReachable()
    } catch {
        print(error)
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.