IOS开发-数据持久化(一)【文本文件+二进制归档】

概要

    数据持久化分为不同的方式,本章主要简示了数据归档(一般而说的序列化)和写XML的文本文件方式。其中XML文本方式主要使用NSArray或者NSDictionary的writeToFile方法,而数据归档使用了NSKeyedArchiver/NSKeyedUnarchiver等实现数据的归档(序列化)。


结果展示


程序展示


数据化文件

      注意新版本的IOS模拟器的目录和以前的目录不在同一个地方,其中plist文件是XML文件,可打开直接查看,而archi是归档的二进制文件。


流程概要


1.新建工程,拖拉界面,完成程序除归档外的操作,具体操作:略

2.对于XML存储,将需要存储的数据放到字典或者数组中,然后调用WriteToFile把数据保存到文件,使用类方法initWithContentsOfFile读取存储的数据即可

3.数据归档化相对而言较复杂点,需要新建一个数据类,该类需要实现了NSCoding协议,然后实现编码和解码两个方法。

4.在需要数据存储的地方把需要的数据放到步骤3中的数据类的对象中,然后结合使用NSMutableData和NSKeyedArchiver实现数据归档。

5.略


主要代码

数据类

h文件
//
//  Staff.h
//  DataXMLArchiver
//
//  Created by God Lin on 14/12/9.
//  Copyright (c) 2014年 arbboter. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Staff : NSObject <NSCoding>
{
    NSString* _nickName;
    NSString* _email;
    NSString* _phone;
    NSString* _sex;
    NSString* _position;
}

@property (nonatomic, retain) NSString* _nickName;
@property (nonatomic, retain) NSString* _email;
@property (nonatomic, retain) NSString* _phone;
@property (nonatomic, retain) NSString* _sex;
@property (nonatomic, retain) NSString* _position;
@end

m文件
//
//  Staff.m
//  DataXMLArchiver
//
//  Created by God Lin on 14/12/9.
//  Copyright (c) 2014年 arbboter. All rights reserved.
//

#import "Staff.h"

@implementation Staff

@synthesize _nickName;
@synthesize _email;
@synthesize _phone;
@synthesize _sex;
@synthesize _position;

#pragma NSCoding 实现序列化(归档)
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self._nickName forKey:@"nickName"];
    [aCoder encodeObject:self._email forKey:@"email"];
    [aCoder encodeObject:self._phone forKey:@"phone"];
    [aCoder encodeObject:self._sex forKey:@"sex"];
    [aCoder encodeObject:self._position forKey:@"position"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self._nickName = [aDecoder decodeObjectForKey:@"nickName"];
    self._email = [aDecoder decodeObjectForKey:@"email"];
    self._phone = [aDecoder decodeObjectForKey:@"phone"];
    self._sex = [aDecoder decodeObjectForKey:@"sex"];
    self._position = [aDecoder decodeObjectForKey:@"position"];
    return self;
}
@end


程序主体代码

h文件
//
//  ViewController.h
//  DataXMLArchiver
//
//  Created by God Lin on 14/12/9.
//  Copyright (c) 2014年 arbboter. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    IBOutlet UITextField* _textNickName;
    IBOutlet UITextField* _textEmail;
    IBOutlet UITextField* _textPhone;
    IBOutlet UITextField* _textSex;
    IBOutlet UITextField* _textPosition;
}
@property (nonatomic, retain) UITextField* _textNickName;
@property (nonatomic, retain)UITextField* _textEmail;
@property (nonatomic, retain)UITextField* _textPhone;
@property (nonatomic, retain)UITextField* _textSex;
@property (nonatomic, retain)UITextField* _textPosition;

-(IBAction)onHideKeyboard:(id)sender;
-(IBAction)onXmlSave:(id)sender;
-(IBAction)onXmlLoad:(id)sender;
-(IBAction)onArchiverSave:(id)sender;
-(IBAction)onArchiverLoad:(id)sender;
@end

m文件
//
//  ViewController.m
//  DataXMLArchiver
//
//  Created by God Lin on 14/12/9.
//  Copyright (c) 2014年 arbboter. All rights reserved.
//

#import "ViewController.h"
#import "Staff.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize _textNickName;
@synthesize _textEmail;
@synthesize _textPhone;
@synthesize _textSex;
@synthesize _textPosition;


-(IBAction)onHideKeyboard:(id)sender
{
    [sender resignFirstResponder];
}
-(NSString*)getDocumentDir
{
    // 获取保存的文件名
    NSArray* arrayPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [arrayPath objectAtIndex:0];
}
-(void)textClear
{
    self._textNickName.text = @"";
    self._textEmail.text = @"";
    self._textPhone.text = @"";
    self._textSex.text = @"";
    self._textPosition.text = @"";
}

// XML文本保存数据,可使用数组字典等保存数据
-(IBAction)onXmlSave:(id)sender
{
    // 保存数据到字典
    NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
    [dict setObject:self._textNickName.text forKey:@"nickName"];
    [dict setObject:self._textEmail.text forKey:@"email"];
    [dict setObject:self._textPhone.text forKey:@"phone"];
    [dict setObject:self._textSex.text forKey:@"sex"];
    [dict setObject:self._textPosition.text forKey:@"position"];
    
    NSString* pathFile = [self getDocumentDir];
    pathFile = [pathFile stringByAppendingPathComponent:@"staff.plist"];
    
    // 数据写入文件
    [dict writeToFile:pathFile atomically:YES];
    
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Infomation" message:@"Save finished" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    // 使用ARC,自己不需要管理内存
    //[alert release];
    [self textClear];
}
-(IBAction)onXmlLoad:(id)sender
{
    // 获取保存的文件名
    NSString* pathFile = [self getDocumentDir];
    pathFile = [pathFile stringByAppendingPathComponent:@"staff.plist"];
    
    NSDictionary* dict = [[NSDictionary alloc] initWithContentsOfFile:pathFile];
    self._textNickName.text = [dict objectForKey:@"nickName"];
    self._textEmail.text = [dict objectForKey:@"email"];
    self._textPhone.text = [dict objectForKey:@"phone"];
    self._textSex.text = [dict objectForKey:@"sex"];
    self._textPosition.text = [dict objectForKey:@"position"];
    
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Infomation" message:@"Load finished" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
}

// 归档化数据
-(IBAction)onArchiverSave:(id)sender
{
    Staff* staff = [[Staff alloc] init];
    staff._nickName = self._textNickName.text;
    staff._email = self._textEmail.text;
    staff._phone = self._textPhone.text;
    staff._sex = self._textSex.text;
    staff._position = self._textPosition.text;
    
    // 新建二进制内存(读写)
    NSMutableData* data = [[NSMutableData alloc] init];
    
    // 设置二进制内存数据内容(读写)
    NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:staff forKey:@"staff"];
    [archiver finishEncoding];
    
    // 获取保存的文件名
    NSString* pathFile = [self getDocumentDir];
    pathFile = [pathFile stringByAppendingPathComponent:@"staff.archi"];
    
    // 保存数据(归档)
    [data writeToFile:pathFile atomically:YES];
    
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Infomation" message:@"Archive finished" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [self textClear];
}
-(IBAction)onArchiverLoad:(id)sender
{
    // 获取保存的文件名
    NSString* pathFile = [self getDocumentDir];
    pathFile = [pathFile stringByAppendingPathComponent:@"staff.archi"];
    
    // 读取归档文件到内存(只读)
    NSData* data = [NSData dataWithContentsOfFile:pathFile];
    
    // 解码内存数据(只读)
    NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    Staff* staff = [unarchiver decodeObjectForKey:@"staff"];
    [unarchiver finishDecoding];
    
    self._textNickName.text = staff._nickName;
    self._textEmail.text = staff._email;
    self._textPhone.text = staff._phone;
    self._textSex.text = staff._sex;
    self._textPosition.text = staff._position;
    
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Infomation" message:@"Load from Archiver finished" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


工程代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的文本文件二进制文件也有类似Python的区别。下面是一些代码示例,来说明二者的不同之处。 文本文件的读写: ```c++ #include <iostream> #include <fstream> #include <string> using namespace std; int main() { // 打开文件 ofstream outfile("textfile.txt"); // 写入数据 outfile << "Hello World!" << endl; // 关闭文件 outfile.close(); // 打开文件 ifstream infile("textfile.txt"); // 读取数据 string text; while (getline(infile, text)) { cout << text << endl; } // 关闭文件 infile.close(); return 0; } ``` 在这个示例中,我们使用 `ofstream` 和 `ifstream` 两个类来分别写入和读取文本文件。`ofstream` 用于写入文件,`ifstream` 用于读取文件。在写入文件时,我们可以使用 `<<` 操作符将数据写入文件,这里我们写入了一个字符串 "Hello World!" 和一个换行符。在读取文件时,我们使用 `getline()` 函数来逐行读取文件中的内容,然后输出到控制台上。 二进制文件的读写: ```c++ #include <iostream> #include <fstream> using namespace std; struct Person { char name[20]; int age; }; int main() { // 创建结构体数据 Person person = {"Tom", 23}; // 打开文件 ofstream outfile("binaryfile.bin", ios::out | ios::binary); // 写入数据 outfile.write(reinterpret_cast<char*>(&person), sizeof(Person)); // 关闭文件 outfile.close(); // 打开文件 ifstream infile("binaryfile.bin", ios::in | ios::binary); // 读取数据 Person person2; infile.read(reinterpret_cast<char*>(&person2), sizeof(Person)); // 关闭文件 infile.close(); // 输出数据 cout << "Name: " << person2.name << endl; cout << "Age: " << person2.age << endl; return 0; } ``` 在这个示例中,我们使用结构体 `Person` 来存储数据,并将其写入二进制文件。在写入文件时,我们使用 `write()` 函数来写入数据。需要注意的是,由于二进制文件不是文本文件,因此我们需要将结构体的指针转换为字符指针,即使用 `reinterpret_cast<char*>()` 进行类型转换。在读取文件时,我们使用 `read()` 函数来读取数据,同样需要进行类型转换。最后,我们输出读取的数据。 总的来说,文本文件二进制文件都有各自的优缺点,应根据实际需求来选择使用哪种类型的文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值