จะตรวจสอบว่ามีไฟล์อยู่ในโฟลเดอร์เอกสารได้อย่างไร?


216

ฉันมีแอปพลิเคชันพร้อม In-App Purchase ซึ่งเมื่อผู้ใช้ซื้อบางอย่างให้ดาวน์โหลดไฟล์ 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)

Objective-C:

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

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

12
โปรดทราบว่าคุณกำลังโหลดไฟล์ออกจากไดเรกทอรีเอกสารส่วนตัวของแอปพลิเคชันไม่ใช่ไฟล์ทั่วโลกที่คุณพบว่าคุณถูกเจลเบรค หากคุณติดตั้งแอปพลิเคชันของคุณใน / Applications ราวกับเป็นแอปพลิเคชันหลักคุณจะสามารถเข้าถึงระบบไฟล์ทั้งหมดและคุณจะใช้ไดเรกทอรีเอกสารที่แชร์ หากคุณติดตั้งผ่าน iTunes หรือ XCode คุณจะใช้ไดเรกทอรีส่วนตัวของแอปพลิเคชันของคุณ ยินดีที่จะเก็บไฟล์ไว้ในไดเรกทอรีภายในเครื่องของคุณเพื่อการสำรองข้อมูล
Epsilon Prime

6
objectAtIndex: 0 สามารถถูกแทนที่ด้วยตอนแรกอ็อบเจ็ก
Govind

3
หรือเพียงแค่[0]เข้าถึงดัชนี
temporary_user_name

firstObject ปลอดภัยกว่า [0] และ objectAtIndex: 0
Itachi

1
@ Itachi ที่จริงแล้วในกรณีนี้ฉันชอบข้อยกเว้นเมื่อไม่มีวัตถุในอาร์เรย์ หากผลการfirstObjectคือnilไม่มีวิธีที่เหมาะสมวิธีการที่โปรแกรมได้อย่างต่อเนื่องเป็นสิ่งที่อยู่ในกรอบแอปเปิ้ลที่ถูกทำลายอย่างจริงจัง
Nikolai Ruhe

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

Swift 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)
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.