Como verificar se existe um arquivo na pasta Documentos?

216

Eu tenho um aplicativo com a compra no aplicativo que, quando o usuário compra algo, baixe um arquivo html na pasta Documents do meu aplicativo.

Agora, devo verificar se esse arquivo HTML existe; portanto, se for verdadeiro, carregue esse arquivo HTML, caso contrário, carregue minha página html padrão.

Como eu posso fazer isso? Com NSFileManagereu não posso sair de mainBundle..

Obliviux
fonte
"Com o NSFileManager, não consigo sair do mainBundle" - de onde você tirou essa informação errada?

Respostas:

521

Swift 3:

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

... fornece um URL de arquivo do diretório de documentos. A seguir, verifica se há um arquivo chamado foo.html:

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

Objetivo-C:

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

NSString* foofile = [documentsPath stringByAppendingPathComponent:@"foo.html"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
Nikolai Ruhe
fonte
12
Observe que você está carregando um arquivo fora do diretório Documentos pessoal do seu aplicativo, não o global que você encontra se estiver com jailbreak. Se você instalar o aplicativo em / Applications como se fosse um aplicativo principal, terá acesso a todo o sistema de arquivos e usará o diretório Documents compartilhado. Se você instalá-lo via iTunes ou XCode, estará usando o diretório pessoal de seus aplicativos. É bom armazenar arquivos no diretório local para fins de backup.
Epsilon Prime
6
objectAtIndex: 0 agora pode ser substituído por firstObject
Govind
3
Ou apenas [0]acessando o índice
temporary_user_name
firstObject é mais seguro que [0] e objectAtIndex: 0
Itachi
1
@ Ittachi Na verdade, neste caso, prefiro a exceção quando não há objeto na matriz. Se o resultado firstObjecté que nilnão há uma maneira sensata de como o programa poderia continuar, pois algo nas estruturas da Apple está seriamente quebrado.
Nikolai Ruhe
14

A Apple recomenda não confiar no método fileExistAtPath:. Geralmente, é melhor apenas tentar abrir um arquivo e lidar com o erro se o arquivo não existir.

Referência da classe NSFileManager

Nota: Não é recomendável tentar predicar o comportamento com base no estado atual do sistema de arquivos ou em um arquivo específico no sistema de arquivos. Fazer isso pode causar comportamentos estranhos ou condições de corrida. É muito melhor tentar uma operação (como carregar um arquivo ou criar um diretório), verificar se há erros e lidar com esses erros normalmente do que tentar descobrir com antecedência se a operação será bem-sucedida. Para obter mais informações sobre as condições de corrida do sistema de arquivos, consulte “Condições de corrida e operações seguras de arquivos” no Guia de codificação segura.

Fonte: Referência da API do desenvolvedor Apple

No guia de codificação seguro.

Para evitar isso, os programas costumam verificar se um arquivo temporário com um nome específico ainda não existe no diretório de destino. Se esse arquivo existir, o aplicativo o exclui ou escolhe um novo nome para o arquivo temporário para evitar conflitos. Se o arquivo não existir, o aplicativo abrirá o arquivo para gravação, porque a rotina do sistema que abre um arquivo para gravação cria automaticamente um novo arquivo, se não houver nenhum. Um invasor, executando continuamente um programa que cria um novo arquivo temporário com o nome apropriado, pode (com um pouco de persistência e alguma sorte) criar o arquivo no intervalo entre quando o aplicativo foi verificado para garantir que o arquivo temporário não existisse. e quando abre para escrever. O aplicativo abre o arquivo do invasor e grava nele (lembre-se, a rotina do sistema abre um arquivo existente, se houver um, e cria um novo arquivo apenas se não houver arquivo). O arquivo do invasor pode ter permissões de acesso diferentes do arquivo temporário do aplicativo, para que o invasor possa ler o conteúdo. Como alternativa, o invasor pode ter o arquivo já aberto. O invasor pode substituir o arquivo por um link físico ou simbólico para outro arquivo (de propriedade do invasor ou de um arquivo de sistema existente). Por exemplo, o invasor pode substituir o arquivo por um link simbólico para o arquivo de senha do sistema, para que, após o ataque, as senhas do sistema sejam corrompidas a ponto de ninguém, incluindo o administrador do sistema, poder efetuar login. Como alternativa, o invasor pode ter o arquivo já aberto. O invasor pode substituir o arquivo por um link físico ou simbólico para outro arquivo (de propriedade do invasor ou de um arquivo de sistema existente). Por exemplo, o invasor pode substituir o arquivo por um link simbólico para o arquivo de senha do sistema, para que, após o ataque, as senhas do sistema sejam corrompidas a ponto de ninguém, incluindo o administrador do sistema, poder efetuar login. Como alternativa, o invasor pode ter o arquivo já aberto. O invasor pode substituir o arquivo por um link físico ou simbólico para outro arquivo (de propriedade do invasor ou de um arquivo de sistema existente). Por exemplo, o invasor pode substituir o arquivo por um link simbólico para o arquivo de senha do sistema, para que, após o ataque, as senhas do sistema sejam corrompidas a ponto de ninguém, incluindo o administrador do sistema, poder efetuar login.

orkoden
fonte
1
Embora esta seja uma boa resposta por si só, fornecemos ótimos conselhos. Seria bom ver como isso poderia ser implementado com um pequeno exemplo de código.
SnareChops
8

Se você configurar seu sistema de arquivos de maneira diferente ou procurar uma maneira diferente de configurar um sistema de arquivos e, em seguida, verificar se existe um arquivo na pasta de documentos, veja outro exemplo. também mostram verificação dinâmica

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
fonte
4

Swift 2.0

Veja como verificar se o arquivo existe usando o 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)
}
Tal Zion
fonte
3

verifique se o arquivo existe ao lado do caminho do documento / captura de imagem:

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
fonte
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
fonte
0

NSURL.h fornecido - (BOOL)checkResourceIsReachableAndReturnError:(NSError **)errorpara fazer isso

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

Ou usando Swift

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