您的位置:首页 > 其它

ObjC第七节:文件操作

2015-08-21 19:48 309 查看
文件操作

1、简介

2、NSCoding(归档解档)

3、管理文件和目录

文件管理

//写文件,我们之前使用各种数据结构来存储数据:NSString,NSData,NSDictionary,NSArray等,他们都是有一个writeToFile方法用来写文件的

//纯文本:没有任何格式的数据
//非纯文本:有修饰的数据(字体大小,字体颜色等)

//数组只能将如下类型写入文件,如果包含其他对象,将写入失败:NSNumber,NSString,NSData,NSDate,NSArray,NSDictionary
//数组、字典写入的文件叫做属性文件,可以使用xcode进行编辑

//现在有这样的场景,第一次把字符串写入到文件中,当我们修改字符串之后,再次写入的时候,但是可能会写入失败
//但是之前的内容也有可能丢失,因为每次在写入新的内容的时候,会剪切之前的内容,所以这里就有可能新的没有写
//成功,旧的文件也丢失了
//所以这时候atomically参数:
//YES:会将新内容先写入到一个缓存文件中,如果写入缓存成功之后,这时候就将这个缓存文件替换旧文件,这样就很安全了
#import <Foundation/Foundation.h>
#import "Baby.h"
int main(int argc, const char * argv[])
{
@autoreleasepool
{
NSFileManager * fm = [NSFileManager defaultManager];
//获取当前目录(相对路径)
NSString * strp = [fm currentDirectoryPath];
NSLog(@"%@", strp);
//设置绝对路径
NSString * path = @"/Users/len/Desktop";
//通过相对路径设置文件路径
NSString * path1 = [strp stringByAppendingString:@"/1111.txt"];
//创建目录(可以顺便创建文件)
//[[NSFileManager defaultManager] createDirectoryAtPath:path1 withIntermediateDirectories:YES attributes:nil error:nil];
//创建文件
[fm createFileAtPath:path1 contents:nil attributes:nil];
//文件写入(字符)
[strp writeToFile:path1 atomically:YES encoding:NSUTF8StringEncoding error:nil];
//文件读取(字符串)
NSString * str1 = [NSString stringWithContentsOfFile:path1 encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@", str1);
//文件读取(二进制流)
NSLog(@"%@", [fm contentsAtPath:path1]);//NSData
//文件写入(数组)
NSArray * arr = @[@"11", @"22", @"aa"];
[arr writeToFile:path1 atomically:YES];
//文件读取(数组)
NSArray * arr1 = [NSArray arrayWithContentsOfFile:path1];
NSLog(@"%@", arr1);
//文件的属性字典
NSDictionary * dic = [fm attributesOfItemAtPath:path1 error:nil];
//字典的键NSFileSize对应文件的大小
int size = [[dic objectForKey:NSFileSize] intValue];
//文件读取(二进制流转化为字符串)(输出文件的所有内容而不仅仅是存入的对象的值)
NSData * data = [fm contentsAtPath:path1];
NSString * strData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@, %d, %@, %@", dic, size, data, strData);

//查看文件是否存在、新建、拷贝、删除
NSError * error ;
if ([fm fileExistsAtPath:path1])
{
[fm copyItemAtPath:path1 toPath:[path stringByAppendingString:@"/2222.txt"] error:nil];//如果没有2222这个文件,会自动创建。此处文件前的/,代表着目录的层次(本级还是上一级)
[fm createFileAtPath:[strp stringByAppendingString:@"/3333.docx"] contents:nil attributes:nil]; //如果没有则自动创建,docx成功
[fm copyItemAtPath:path1 toPath:[strp stringByAppendingString:@"/3333.docx"] error: &error];//docx可能无法写入?
[fm removeItemAtPath:path1 error:nil]; //删除1111
}

// NSString * path1 = [NSString stringWithFormat:@"%@/Desktop/1111.txt", NSHomeDirectory()];
// //路径的组成部分
// NSString * pathPart = [path1 pathComponents]; //第一个是"/",也是路径的一部分
// //路径的最后组成部分
// NSString * pathLast = [path1 lastPathComponent];
// //获取扩展名
// NSString * pathEX = [path1 pathExtension];
// //删除扩展名(.txt被删除了)
// NSString * pathDelEX = [path1 stringByDeletingPathExtension];
// //删除最后的组成部分
// NSString * pathDel = [path1 stringByDeletingLastPathComponent];
// //在原有的路径后面追加子目录
// //string需要添加/
// NSString * pathAddS = [pathDel stringByAppendingString:@"/AddString.txt"];
// //pathComponent不需要添加/
// NSString * pathAddP = [pathDel stringByAppendingPathComponent:@"AddString.txt"];
// //添加扩展名
// NSString * pathAddEX = [pathDelEX stringByAppendingPathExtension:@"docx"];
// NSLog(@"%@, %@", path1, pathAddEX);
//
// NSString * path2 = [path1 stringByExpandingTildeInPath];
// NSString * path3 = [path1 stringByResolvingSymlinksInPath];
// NSString * path4 = [path1 stringByStandardizingPath];

// NSLog(@"%@", NSHomeDirectory()); //返回主目录:/ueses/len
// NSLog(@"%@", NSHomeDirectoryForUser(@"zmm")); //返回用户主目录:len为null,zmm为:/ueses/len
// NSLog(@"%@", NSUserName()); //返回用户名(登录名):zmm
// NSLog(@"%@", NSFullUserName()); //返回用户名(全名):zmm
// NSLog(@"%@", NSTemporaryDirectory()); //返回一个目录的路径,可以用来创建临时文件

// NSString *s = @"tsdfsdfsdfsdf";
// NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding];
// s = [[NSString alloc] initWithData:data encoding:(NSUTF8StringEncoding)];
//
// NSData *data1 = [NSData dataWithBytes:s length:[s length]];

// Baby * b = [[Baby alloc] initWithAge:12 andName:@"AA" andScore:99];
// [b print];
//
// NSString * pathDirectory = [NSString stringWithFormat:@"%@/Documents/bb.txt", NSHomeDirectory()];
//
// [NSKeyedArchiver archiveRootObject:b toFile:pathDirectory];
//
// Baby * b1 = [NSKeyedUnarchiver unarchiveObjectWithFile:pathDirectory];
// [b1 print];

}
return 0;
}
#import <Foundation/Foundation.h>
int main ()
{
//fm
NSFileManager * fm = [NSFileManager defaultManager];
//获取主目录
NSString * home = NSHomeDirectory();
//桌面目录
NSString * path = [home stringByAppendingPathComponent:@"Desktop"];
//文件夹目录
NSString * filePath = [path stringByAppendingString:@"/练习"];
//文件内容
NSString * str = @"iOS棒棒棒~~~";
//文件内容转化为data(当然也可以直接写入文件)
NSData * data = [str dataUsingEncoding:NSUTF8StringEncoding];
//创建目录(withIntermediateDirectories:YES,此时可以创建多级不存在的目录,NO则不可以)
[fm createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
//创建文件,同时把内容写进去
BOOL create = [fm createFileAtPath:[filePath stringByAppendingPathComponent:@"file1.txt"] contents:data attributes:nil];
NSString * filePath2 = [filePath stringByAppendingPathComponent:@"file1.txt"];
if (create)  //判断成功与否
{
NSLog(@"YES");
}
else
{
NSLog(@"NO");
}
//文件读取(字符串)
NSString * strFile1 = [NSString stringWithContentsOfFile:filePath2 encoding:NSUTF8StringEncoding error:nil];
//文件读取(data转化字符串)(此时输出一样,如果是数组,则下面的方法输出所有文字信息)
NSData * data2 = [fm contentsAtPath:filePath2];
NSString * strData = [[NSString alloc] initWithData:data2 encoding:NSUTF8StringEncoding];
NSLog(@"%@, %@", strData, strFile1);
//拷贝file1到file2,注意是内容拷贝,需要创建文件(即路径要指定文件),但当目标路径的文件已经存在时,不进行拷贝,即不会覆盖
BOOL copyF = [fm copyItemAtPath:filePath2 toPath:[filePath stringByAppendingPathComponent:@"file2.txt"] error:nil];
if (copyF)  //判断成功与否
{
NSLog(@"YES");
}
else
{
NSLog(@"NO");
}
//移动/剪切file2到file3,即使目标路径的文件名不一致,也可以进行并重命名为新名,如果目标名已经存在,则没有进行剪切,即不会覆盖
BOOL move = [fm moveItemAtPath:[filePath stringByAppendingPathComponent:@"file2.txt"] toPath:[filePath stringByAppendingPathComponent:@"file/file3.txt"] error:nil];
if (move)  //判断成功与否
{
NSLog(@"YES");
}
else
{
NSLog(@"NO");
}
//删除文件file1,删除前需要判断是否存在
if ([fm fileExistsAtPath:filePath2])
{
BOOL del = [fm removeItemAtPath:filePath2 error:nil];
if (del)  //判断成功与否
{
NSLog(@"YES");
}
else
{
NSLog(@"NO");
}
}
//查看文件属性(字典)
NSDictionary * dic = [fm attributesOfItemAtPath:[filePath stringByAppendingPathComponent:@"file/file3.txt"] error:nil];
//通过键获得某个指定属性,以下两种方式结果一样
long size = [dic fileSize];  //通过fileSize
int size2 = [[dic objectForKey:NSFileSize] intValue];  //通过键取值
NSLog(@"%@,%ld,%d", dic, size, size2);

return 0;
}
NSFileHandle

//NSFileHandle
#import <Foundation/Foundation.h>
int main ()
{
//文件路径
NSString * filePath = [NSString stringWithFormat:@"%@/Desktop/练习/FileHandle.txt", NSHomeDirectory()];
//文件内容
NSString * strFile = @"abcdefg,higklmn";
//写入文件
BOOL write = [strFile writeToFile:filePath atomically:NO encoding:NSUTF8StringEncoding error:nil];
//判断是否写入成功
if (write){
NSLog(@"YES");
}
else {
NSLog(@"NO");
}
//创建写入的FH

c27f
NSFileHandle * fhW = [NSFileHandle fileHandleForWritingAtPath:filePath];
//把FH移动到文件尾
[fhW seekToEndOfFile];
//添加的内容
NSString * addStr = @"123456";
//添加的内容转为data
NSData * data = [addStr dataUsingEncoding:NSUTF8StringEncoding];
//写入文件
[fhW writeData:data];
//关闭文件
[fhW closeFile];
//创建读取的FH
NSFileHandle * fhR = [NSFileHandle fileHandleForReadingAtPath:filePath];
//创建FM
NSFileManager * fm = [NSFileManager defaultManager];
//文件属性
NSDictionary * attr = [fm attributesOfItemAtPath:filePath error:nil];
//用键取得文件size
int size = [[attr objectForKey:NSFileSize] intValue];
//设置偏移量,为文件中间
[fhR seekToFileOffset:size/2]; //不能用写的FH读取
//从当前偏移量读取到文件尾
NSData * data2 = [fhR readDataToEndOfFile];
//转化为字符串
NSString * readStr = [[NSString alloc] initWithData:data2 encoding:NSUTF8StringEncoding];
NSLog(@"%@", readStr);

[readStr release];
[fhW closeFile];
[fhR closeFile];

return 0;

}NSCoding

Baby

#import <Foundation/Foundation.h>

@interface Baby : NSObject <NSCoding>

@property (nonatomic) int age;
@property (nonatomic, retain) NSString * name;
@property (nonatomic) double score;

- (id)initWithAge:(int)a andName:(NSString *)n andScore:(double)s;
- (void)print;

@end
#import "Baby.h"

@implementation Baby

- (id)initWithAge:(int)a andName:(NSString *)n andScore:(double)s
{
if (self = [super init])
{
_age = a;
self.name = n;
_score = s;
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
//[aCoder encodeObject:[NSNumber numberWithInt:_age] forKey:@"1"];
[aCoder encodeInt:_age forKey:@"1"]; //encodeInt 与 decodeInt必须同时使用,与上面效果一样
[aCoder encodeObject:_name forKey:@"2"];
[aCoder encodeObject:[NSNumber numberWithDouble:_score] forKey:@"3"]; //与int一样
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init])
{
//_age = [[aDecoder decodeObjectForKey:@"1"] intValue];//不写intValue,可能会输出错误
self.age = [aDecoder decodeIntForKey:@"1"]; //decodeInt
self.name = [aDecoder decodeObjectForKey:@"2"];
_score = [[aDecoder decodeObjectForKey:@"3"] doubleValue];
}
return self;
}

- (void)print
{
NSLog(@"Age = %d, name = %@, score = %.2lf", _age, _name, _score);
}

- (void)dealloc
{
[_name release];
[super dealloc];
}

@endmain.m

#import <Foundation/Foundation.h>
#import "Baby.h"
int main ()
{
Baby * b1 = [[Baby alloc] initWithAge:1 andName:@"AA" andScore:2];
Baby * b2 = [[Baby alloc] initWithAge:12 andName:@"AA" andScore:99];
//[b2 print];

NSArray * arr = @[b1, b2, b1, b2];
[arr makeObjectsPerformSelector:@selector(print)];

NSString * path = @"/Users/len/Desktop/BabyArray2.rtf";

[NSKeyedArchiver archiveRootObject:arr toFile:path];
NSArray * arr2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

[arr2 makeObjectsPerformSelector:@selector(print)];
//[@"123456123456123456" writeToFile:@"/Users/len/Desktop/2222.txt" atomically:NO encoding:NSUTF8StringEncoding error:nil]; //覆盖掉原来的内容

return 0;
}一道练习

Computer

#import <Foundation/Foundation.h>

@interface Computer : NSObject <NSCoding>

@property (nonatomic) float width;
@property (nonatomic, retain) NSString *name;

- (id) initWithWidth:(float)_width andName:(NSString *)_name;
- (void) print;

@end
#import "Computer.h"

@implementation Computer

@synthesize width, name;

- (id) initWithWidth:(float)_width andName:(NSString *)_name
{
if (self = [super init])
{
width = _width;
self.name = _name;
}
return self;
}

- (void) print
{
NSLog(@"Width = %.2lf, Name = %@", width, name);
}

- (void) dealloc
{
[name release];
[super dealloc];
}

#pragma mark --code
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"a"];
[aCoder encodeFloat:width forKey:@"b"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init])
{
self.name = [aDecoder decodeObjectForKey:@"a"];
width = [aDecoder decodeFloatForKey:@"b"];
}
return self;
}

@endPerson

#import <Foundation/Foundation.h>
#import "Computer.h"

@interface Person : NSObject <NSCopying, NSCoding>
{
NSString *name;
Computer * c;
int age;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) Computer * c;
@property (nonatomic) int age;

- (id) initWithName:(NSString *)_name andAge:(int)_age andComputer:(Computer *)_c;
- (void) print;

@end
#import "Person.h"

@implementation Person

@synthesize name, age, c;

- (id) initWithName:(NSString *)_name andAge:(int)_age andComputer:(Computer *)_c
{
if (self = [super init])
{
self.name = _name;
age = _age;
self.c = _c;
}
return self;
}

- (void) print
{
[c print];
NSLog(@"PName = %@, Age = %d", name, age);
}

- (void)dealloc
{
[name release];
[c release];
[super dealloc];
}

#pragma mark --copy
- (id)copyWithZone:(NSZone *)zone
{
Person * newPerson = [[Person allocWithZone:zone] initWithName:name andAge:age andComputer:c];
// newPerson.name = name;
// newPerson.age = age;
// newPerson.c = c;
return newPerson;
}

#pragma mark --code
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"1"];
[aCoder encodeObject:self.c forKey:@"2"];
// [aCoder encodeObject:self.c.name forKey:@"a"];
// [aCoder encodeFloat:self.c.width forKey:@"b"];
[aCoder encodeInt:age forKey:@"3"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init])
{
self.name = [aDecoder decodeObjectForKey:@"1"];
self.c = [aDecoder decodeObjectForKey:@"2"];
// self.c.name = [aDecoder decodeObjectForKey:@"a"];
// self.c.width = [aDecoder decodeFloatForKey:@"b"];
age = [aDecoder decodeIntForKey:@"3"];
}
return self;
}

@endSon

#import <Foundation/Foundation.h>
#import "Person.h"

@interface Son : Person

@property (nonatomic) int num;

- (id)initWithNum:(int)_num andName:(NSString *)_name andAge:(int)_age andComputer:(Computer *)_c;
- (void) print;

@end
#import "Son.h"

@implementation Son

@synthesize num;

- (id)initWithNum:(int)_num andName:(NSString *)_name andAge:(int)_age andComputer:(Computer *)_c
{
if (self = [super initWithName:_name andAge:_age andComputer:_c])
{
num = _num;
}
return self;
}

- (void) print
{
[super print];
NSLog(@"SNum = %d", num);
}

//如果子类不写,则子类归档解档输出为空,其他正常
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[super encodeWithCoder:aCoder]; //如果不写,父类和父类组合类为空
[aCoder encodeInt:num forKey:@"11"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) //如果不写initWith,父类和父类组合类为空
{
num = [aDecoder decodeIntForKey:@"11"];
}
return self;
}

@endmain.m

#import <Foundation/Foundation.h>
#import "Son.h"
int main(int argc, const char * argv[])
{
@autoreleasepool
{
Computer * cc = [[Computer alloc] initWithWidth:1 andName:@"CC"];
Person * pp = [[Person alloc] initWithName:@"PP" andAge:20 andComputer:cc];
[cc print];
[pp print];

Person * p1 = [pp copy];
[p1 print];

NSString * path = [NSString stringWithFormat:@"%@/Documents/hello.txt", NSHomeDirectory()];
[NSKeyedArchiver archiveRootObject:pp toFile:path];
Person * p2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
[p2 print];

Son * s = [[Son alloc] initWithNum:111 andName:@"BB" andAge:20 andComputer:cc];
[s print];
NSString * path2 = [NSString stringWithFormat:@"%@/Documents/hello2.txt", NSHomeDirectory()];
[NSKeyedArchiver archiveRootObject:s toFile:path2];
Person * s2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];
[s2 print];

[s release];
[cc release];
[pp release];
[p1 release];
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ObjC课程