我有一个应用程序内购买的应用程序,当用户购买东西时,将一个html文件下载到我的应用程序的Documents文件夹中。
现在我必须检查这个HTML文件是否存在,如果是,则加载此HTML文件,否则加载我的默认html页面。
我怎么能这样做?使用NSFileManager
我无法超越mainBundle
..
答案 0 :(得分:516)
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)
NSString* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString* foofile = [documentsPath stringByAppendingPathComponent:@"foo.html"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
答案 1 :(得分:13)
Apple建议不要依赖fileExistAtPath:方法。如果文件不存在,尝试打开文件并处理错误通常会更好。
NSFileManager类参考
注意:建议不要尝试基于文件系统的当前状态或文件系统上的特定文件来预测行为。这样做可能会导致奇怪的行为或竞争条件。尝试执行操作(例如加载文件或创建目录),检查错误以及优雅地处理这些错误要比尝试提前判断操作是否成功要好得多。有关文件系统竞争条件的详细信息,请参阅“安全编码指南”中的“竞争条件和安全文件操作”。
来源:Apple Developer API Reference
来自安全编码指南。
为了防止这种情况,程序经常检查以确保目标目录中不存在具有特定名称的临时文件。如果存在此类文件,则应用程序将删除该文件或为临时文件选择新名称以避免冲突。如果该文件不存在,则应用程序将打开要写入的文件,因为打开文件以进行写入的系统例程会自动创建新文件(如果不存在)。 攻击者通过持续运行一个程序来创建一个具有适当名称的新临时文件,可以(稍加一点点运气)在应用程序检查以确保临时文件不存在之间的间隙中创建文件当它打开它写作。然后,应用程序打开攻击者的文件并写入该文件(请记住,如果存在,系统例程将打开现有文件,并且仅在没有现有文件时才创建新文件)。 攻击者的文件可能具有与应用程序的临时文件不同的访问权限,因此攻击者可以读取内容。或者,攻击者可能已经打开了该文件。攻击者可以使用硬链接或符号链接替换该文件到其他文件(攻击者拥有的文件或现有系统文件)。例如,攻击者可以使用指向系统密码文件的符号链接替换该文件,以便在攻击之后,系统密码已损坏,使得包括系统管理员在内的任何人都无法登录。
答案 2 :(得分: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;
}
}
答案 3 :(得分:4)
Swift 2.0
这是使用Swift检查文件是否存在的方法
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object item = parent.getAdapter().getItem(position);
if ( /* your condition here */ ) {
} else if ( /* something else */ ) {
}
}
});
答案 4 :(得分:3)
检查文档/ 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**
}
答案 5 :(得分: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
}
答案 6 :(得分: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)
}
}