Як перевірити, чи існує файл у папці Документи?


216

У мене є програма закупівлі через додаток, яка, коли користувач щось купує, завантажує один html-файл у папку «Документи» мого додатка.

Тепер я повинен перевірити, чи існує цей HTML-файл, тому, якщо це правда, завантажте цей HTML-файл, інакше завантажте мою сторінку HTML за замовчуванням.

Як я можу це зробити? З NSFileManagerя не можу вийти за межі mainBundle..


"З NSFileManager я не можу вийти за межі mainBundle" - звідки ви взяли цю частину дезінформації?

Відповіді:


521

Швидкий 3:

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

... надає URL-адресу файлу в каталозі документів. Наступні перевірки, чи є файл з назвою foo.html:

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

Завдання-C:

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

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

12
Зауважте, що ви завантажуєте файл із особистого каталогу документів вашої програми, а не з глобального, який ви знайдете, якщо ви перебуваєте у в'язниці. Якщо ви встановите свою програму в / Програми так, ніби це була основна програма, ви матимете доступ до всієї файлової системи, і ви будете використовувати спільний каталог документів. Якщо ви встановите його через iTunes або XCode, ви будете використовувати особистий каталог ваших програм. Приємно зберігати файли у вашому локальному каталозі для резервного копіювання.
Епсілон Прем'єр

6
objectAtIndex: 0 тепер можна замінити на firstObject
Govind

3
Або тільки [0]через індекс доступу
temporary_user_name

firstObject є більш безпечним, ніж [0] та objectAtIndex: 0
Itachi

1
@Itachi Насправді в цьому випадку я віддаю перевагу винятку, коли в масиві немає об’єкта. Якщо результат firstObject- nilнемає розумного способу, як програма могла б продовжуватися, оскільки щось в рамках Apple серйозно порушено.
Микола Рухе

14

Apple рекомендує не покладатися на метод fileExistAtPath:. Часто краще просто спробувати відкрити файл і вирішити помилку, якщо файл не існує.

Довідка про клас NSFileManager

Примітка: спроба передбачити поведінку на основі поточного стану файлової системи або певного файлу у файловій системі не рекомендується. Це може спричинити дивну поведінку або перегони. Набагато краще спробувати операцію (наприклад, завантаження файлу чи створення каталогу), перевірити наявність помилок та обробляти ці помилки витончено, ніж це намагатися достроково зрозуміти, чи вдасться виконати операцію. Для отримання додаткової інформації про умови гонки файлової системи див. "Умови гонки та безпечні операції з файлами" в Посібнику з безпечного кодування.

Джерело: Довідник API для розробника Apple

З безпечного посібника з кодування.

Щоб цього не допустити, програми часто перевіряють, щоб переконатися, що тимчасовий файл із конкретним іменем ще не існує в цільовому каталозі. Якщо такий файл існує, програма видаляє його або вибирає нове ім'я для тимчасового файлу, щоб уникнути конфлікту. Якщо цього файлу не існує, програма відкриває файл для запису, оскільки системна програма, яка відкриває файл для запису, автоматично створює новий файл, якщо такий не існує. Зловмисник, безперервно запускаючи програму, яка створює новий тимчасовий файл з відповідним іменем, може (з невеликою наполегливістю та трохи удачі) створити файл у розриві між тим, коли програма перевіряється, щоб переконатися, що тимчасовий файл не існував і коли він відкриває його для написання. Потім програма відкриває файл зловмисника і записує в нього (пам’ятайте, системна процедура відкриває існуючий файл, якщо такий є, і створює новий файл лише у тому випадку, якщо файл не існує). Файл зловмисника може мати різні права доступу, ніж тимчасовий файл програми, тому зловмисник може потім читати вміст. Крім того, зловмисник може вже відкрити файл. Зловмисник може замінити файл жорстким посиланням або символічним посиланням на якийсь інший файл (або той, хто належить зловмиснику, або існуючий системний файл). Наприклад, зловмисник міг би замінити файл символічним посиланням на файл системного пароля, щоб після атаки паролі системи були пошкоджені до того, що ніхто, включаючи системного адміністратора, не зможе увійти. Крім того, зловмисник може вже відкрити файл. Зловмисник може замінити файл жорстким посиланням або символічним посиланням на якийсь інший файл (або той, хто належить зловмиснику, або існуючий системний файл). Наприклад, зловмисник міг би замінити файл символічним посиланням на файл системного пароля, щоб після атаки паролі системи були пошкоджені до того, що ніхто, в тому числі системний адміністратор, не зможе увійти. Крім того, зловмисник може вже відкрити файл. Зловмисник може замінити файл жорстким посиланням або символічним посиланням на якийсь інший файл (або той, хто належить зловмиснику, або існуючий системний файл). Наприклад, зловмисник міг би замінити файл символічним посиланням на файл системного пароля, щоб після атаки паролі системи були пошкоджені до того, що ніхто, в тому числі системний адміністратор, не зможе увійти.


1
Хоча це хороша відповідь, саме він дає чудові поради. Було б добре подивитися, як це можна реалізувати на прикладі невеликого коду.
SnareChops

8

Якщо ви налаштовуєте свою файлову систему по-іншому або шукаєте інший спосіб налаштування файлової системи, а потім перевіряєте, чи існує файл у папці документів, є ще один приклад. також показують динамічну перевірку

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

Швидкий 2.0

Ось як перевірити, чи існує файл за допомогою 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

перевірте, чи існує файл у бік шляху документа / застави:

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 забезпечив - (BOOL)checkResourceIsReachableAndReturnError:(NSError **)errorце

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

Або за допомогою Swift

if let url = URL(fileURLWithPath: NSHomeDirectory()) {
    do {
        let result = try url.checkResourceIsReachable()
    } catch {
        print(error)
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.