Làm thế nào để kiểm tra nếu một tập tin tồn tại trong thư mục Documents?


216

Tôi có một ứng dụng với Mua trong ứng dụng, khi người dùng mua thứ gì đó, hãy tải xuống một tệp html vào thư mục Tài liệu của ứng dụng của tôi.

Bây giờ tôi phải kiểm tra xem tệp HTML này có tồn tại không, vì vậy nếu đúng, hãy tải tệp HTML này, nếu không thì tải trang html mặc định của tôi.

Làm thế nào tôi có thể làm điều đó? Với NSFileManagertôi không thể ra ngoài mainBundle..


"Với NSFileManager tôi không thể ra khỏi mainBundle" - bạn lấy thông tin sai từ đâu?

Câu trả lời:


521

Swift 3:

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

... cung cấp cho bạn một URL tệp của thư mục tài liệu. Các kiểm tra sau nếu có tệp có tên foo.html:

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

Mục tiêu-C:

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

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

12
Lưu ý rằng bạn đang tải một tệp ra khỏi thư mục Tài liệu cá nhân của ứng dụng, chứ không phải tệp toàn cầu bạn tìm thấy nếu bạn đã bẻ khóa. Nếu bạn cài đặt ứng dụng của mình trong / Ứng dụng như thể đó là một ứng dụng chính, bạn sẽ có quyền truy cập vào toàn bộ hệ thống tệp và bạn sẽ sử dụng thư mục Tài liệu được chia sẻ. Nếu bạn cài đặt nó qua iTunes hoặc XCode, bạn sẽ sử dụng thư mục cá nhân của ứng dụng. Thật tuyệt khi lưu trữ các tệp trong thư mục địa phương của bạn cho mục đích sao lưu.
Epsilon Prime

6
objectAt Index: 0 hiện có thể được thay thế bằng FirstObject
Govind

3
Hoặc chỉ [0]thông qua truy cập chỉ mục
tạm

FirstObject an toàn hơn [0] và objectAt Index: 0
Itachi

1
@Itachi Thật ra trong trường hợp này tôi thích ngoại lệ khi không có đối tượng trong mảng. Nếu kết quả firstObjectnilkhông có cách nào hợp lý để làm thế nào chương trình có thể tiếp tục, vì một cái gì đó trong khuôn khổ Apple bị phá vỡ nghiêm trọng.
Nikolai Ruhe

14

Apple khuyến cáo không nên dựa vào phương thức fileExistAtPath :. Sẽ tốt hơn nếu chỉ cố gắng mở một tệp và xử lý lỗi nếu tệp không tồn tại.

Tham khảo lớp NSFileManager

Lưu ý: Không nên cố gắng dự đoán hành vi dựa trên trạng thái hiện tại của hệ thống tệp hoặc một tệp cụ thể trên hệ thống tệp. Làm như vậy có thể gây ra hành vi kỳ lạ hoặc điều kiện chủng tộc. Tốt hơn hết là thử một thao tác (chẳng hạn như tải tệp hoặc tạo thư mục), kiểm tra lỗi và xử lý các lỗi đó một cách duyên dáng hơn là cố gắng tìm hiểu trước liệu hoạt động đó có thành công hay không. Để biết thêm thông tin về các điều kiện chạy đua của hệ thống tệp, hãy xem Điều kiện cuộc đua và các hoạt động tệp an toàn trong Hướng dẫn mã hóa bảo mật.

Nguồn: Tham khảo API của nhà phát triển Apple

Từ hướng dẫn mã hóa an toàn.

Để ngăn chặn điều này, các chương trình thường kiểm tra để đảm bảo một tệp tạm thời có tên cụ thể chưa tồn tại trong thư mục đích. Nếu một tệp như vậy tồn tại, ứng dụng sẽ xóa nó hoặc chọn một tên mới cho tệp tạm thời để tránh xung đột. Nếu tệp không tồn tại, ứng dụng sẽ mở tệp để ghi, vì thói quen hệ thống mở tệp để ghi tự động tạo tệp mới nếu không tồn tại. Kẻ tấn công, bằng cách liên tục chạy một chương trình tạo tệp tạm thời mới với tên thích hợp, có thể (với một chút kiên trì và may mắn) tạo tệp trong khoảng cách giữa khi ứng dụng được kiểm tra để đảm bảo tệp tạm thời không tồn tại và khi nó mở ra để viết. Sau đó, ứng dụng sẽ mở tệp kẻ tấn công và ghi vào nó (hãy nhớ rằng, thói quen hệ thống sẽ mở một tệp hiện có nếu có, và chỉ tạo một tệp mới nếu không có tệp hiện có). Tệp kẻ tấn công có thể có quyền truy cập khác với tệp tạm thời của ứng dụng, do đó kẻ tấn công có thể đọc nội dung. Ngoài ra, kẻ tấn công có thể đã mở tệp. Kẻ tấn công có thể thay thế tệp bằng một liên kết cứng hoặc liên kết tượng trưng cho một số tệp khác (thuộc sở hữu của kẻ tấn công hoặc tệp hệ thống hiện có). Ví dụ, kẻ tấn công có thể thay thế tệp bằng một liên kết tượng trưng đến tệp mật khẩu hệ thống, để sau khi tấn công, mật khẩu hệ thống đã bị hỏng đến mức không ai, kể cả quản trị viên hệ thống, có thể đăng nhập. Ngoài ra, kẻ tấn công có thể đã mở tệp. Kẻ tấn công có thể thay thế tệp bằng một liên kết cứng hoặc liên kết tượng trưng cho một số tệp khác (thuộc sở hữu của kẻ tấn công hoặc tệp hệ thống hiện có). Ví dụ, kẻ tấn công có thể thay thế tệp bằng một liên kết tượng trưng đến tệp mật khẩu hệ thống, để sau khi tấn công, mật khẩu hệ thống đã bị hỏng đến mức không ai, kể cả quản trị viên hệ thống, có thể đăng nhập. Ngoài ra, kẻ tấn công có thể đã mở tệp. Kẻ tấn công có thể thay thế tệp bằng một liên kết cứng hoặc liên kết tượng trưng cho một số tệp khác (thuộc sở hữu của kẻ tấn công hoặc tệp hệ thống hiện có). Ví dụ, kẻ tấn công có thể thay thế tệp bằng một liên kết tượng trưng đến tệp mật khẩu hệ thống, để sau khi tấn công, mật khẩu hệ thống đã bị hỏng đến mức không ai, kể cả quản trị viên hệ thống, có thể đăng nhập.


1
Trong khi đây là một câu trả lời tốt về chính nó cung cấp lời khuyên tuyệt vời. Sẽ rất tốt để xem làm thế nào điều này có thể được thực hiện với một ví dụ mã nhỏ.
SnareChops

8

Nếu bạn thiết lập hệ thống tệp của mình khác nhau hoặc tìm kiếm một cách khác để thiết lập hệ thống tệp và sau đó kiểm tra xem một tệp có tồn tại trong thư mục tài liệu không thì đây là một ví dụ khác. cũng hiển thị kiểm tra động

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

Đây là cách kiểm tra xem tệp có tồn tại bằng Swift không

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

kiểm tra xem tập tin có tồn tại bên cạnh đường dẫn tài liệu / bắt chước không:

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 cung cấp - (BOOL)checkResourceIsReachableAndReturnError:(NSError **)errorđể làm như vậy

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

Hoặc sử dụng Swift

if let url = URL(fileURLWithPath: NSHomeDirectory()) {
    do {
        let result = try url.checkResourceIsReachable()
    } catch {
        print(error)
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.