如何检查“文档”文件夹中是否存在文件?


216

我有一个应用程序内购买应用程序,当用户购买东西时,将一个html文件下载到我应用程序的Documents文件夹中。

现在,我必须检查此HTML文件是否存在,因此,如果为true,则加载此HTML文件,否则加载我的默认html页面。

我该怎么做?随着NSFileManager我无法超越mainBundle..


“有了NSFileManager,我无法进入mainBundle之外”-您从哪里得到这条错误信息?

Answers:


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
请注意,您是从应用程序的个人Documents目录中加载文件,而不是从越狱文件中找到的全局文件。如果您将应用程序安装在/ Applications中,就好像它是主应用程序一样,则您将有权访问整个文件系统,并且将使用共享的Documents目录。如果通过iTunes或XCode安装它,则将使用应用程序的个人目录。最好将文件存储在本地目录中以进行备份。
Epsilon Prime

6
现在可以用firstObject替换objectAtIndex:0
Govind

3
或仅[0]通过索引访问
临时用户名

firstObject比[0]和objectAtIndex:0更安全
Itachi 2016年

1
@Itachi实际上,在这种情况下,我更喜欢数组中没有对象时的异常。如果结果firstObjectnil没有明智的方法,那么该程序将如何继续下去,因为Apple框架中的某些内容已严重损坏。
Nikolai Ruhe

14

苹果建议不要依赖fileExistAtPath:方法。通常最好尝试打开一个文件并处理错误(如果该文件不存在)。

NSFileManager类参考

注意:不建议尝试基于文件系统的当前状态或文件系统上的特定文件来声明行为。这样做可能会导致奇怪的行为或比赛条件。尝试执行某个操作(例如加载文件或创建目录),检查错误并优雅地处理这些错误比尝试提前确定该操作是否成功要好得多。有关文件系统竞争条件的更多信息,请参阅《安全编码指南》中的“种族条件和安全文件操作”。

来源:Apple Developer API参考

来自安全编码指南。

为防止这种情况,程序经常检查以确保目标目录中不存在具有特定名称的临时文件。如果存在这样的文件,则应用程序将其删除或为临时文件选择新名称以避免冲突。如果文件不存在,则应用程序将打开文件进行写入,因为打开文件进行写入的系统例程会自动创建一个新文件(如果不存在)。攻击者可以通过连续运行一个程序来创建一个具有适当名称的新临时文件,从而(稍稍有些持久和有些运气)在应用程序检查以确保该临时文件不存在之间的时间间隔内创建该文件。以及打开它进行书写时。然后,应用程序打开攻击者的文件并对其进行写入(请记住,如果存在,系统例程会打开一个现有文件,并仅在不存在现有文件的情况下创建一个新文件)。攻击者的文件可能具有与应用程序的临时文件不同的访问权限,因此攻击者可以读取内容。或者,攻击者可能已打开文件。攻击者可以使用硬链接或指向其他文件的符号链接替换文件(攻击者拥有的一个文件或现有系统文件)。例如,攻击者可以使用指向系统密码文件的符号链接替换该文件,以便在攻击之后,系统密码已损坏到没有任何人(包括系统管理员)可以登录的程度。或者,攻击者可能已打开文件。攻击者可以使用硬链接或指向其他文件的符号链接替换文件(攻击者拥有的一个文件或现有系统文件)。例如,攻击者可以使用指向系统密码文件的符号链接替换该文件,以便在攻击之后,系统密码已损坏到没有任何人(包括系统管理员)可以登录的程度。或者,攻击者可能已打开文件。攻击者可以用硬链接或指向其他文件的符号链接替换文件(攻击者拥有的一个文件或现有系统文件)。例如,攻击者可以使用指向系统密码文件的符号链接替换该文件,以便在攻击之后,系统密码已损坏到没有任何人(包括系统管理员)可以登录的程度。


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

检查文件是否存在于document / 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

提供- (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error了NSURL.h

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)
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.