IOS lee el archivo de datos binarios

IOS lee el archivo de datos binarios



IOS lee el archivo de datos binarios


En el proceso de desarrollo del proyecto, podemos encontrarnos con los datos que se muestran en la imagen de arriba. De hecho, estos datos son datos binarios almacenados en archivos. Recuerdo que cuando estábamos en la universidad, la maestra nos llevó a escribir un software de contabilidad, en ese momento los datos de la factura se guardaban en un archivo. Describiré brevemente cómo se hizo en ese momento. Primero, debe haber una clase de facturación.

------------------ Archivo de encabezado del tipo de factura ------------------

//

// Payout.h

// Tomar nota

//

// Creado por  Liu Chao  el 12-12-3.

// Copyright (c) 2012 NianLiu Chao . Todos los derechos reservados.

//


#import  <Foundation / Foundation.h>

#define KAmountKey @ "Cantidad"

#define KTimekey @ "Hora"

#define KTypeKey @ "Tipo"

#define KCommentKey @ "Comentario"

 Pago de @interface NSObject < NSCoding , NSCopying >

@property (assign,nonatomic)float amount;

@property (strong,nonatomic)NSDate * time;

@property (strong,nonatomic)NSString * type;

@property (strong,nonatomic)NSString * comment;

-(NSString*)setMoth:(NSDate*)datetime;

-(NSString*)getType;

@end


------------------账单类的原文件-----------------

//

//  Payout.m

//  NoteTaking

//

//  Created by 刘超 on 12-12-3.

//  Copyright (c) 2012刘超. All rights reserved.

//


#import "Payout.h"


@implementation Payout

@synthesize amount;

@synthesize time;

@synthesize type;

@synthesize comment;


-(void)encodeWithCoder:(NSCoder *)encoder

{

    [encoder encodeFloat:amountforKey:KAmountKey];

    [encoder encodeObject:timeforKey:KTimekey];

    [encoder encodeObject:typeforKey:KTypeKey];

    [encoder encodeObject:commentforKey:KCommentKey];

}

-(id)initWithCoder:(NSCoder *)decoder

{

    if (self=[superinit]) {

        amount=[decoderdecodeFloatForKey:KAmountKey];

        time=[decoderdecodeObjectForKey:KTimekey];

        type=[decoderdecodeObjectForKey:KTypeKey];

        comment=[decoderdecodeObjectForKey:KCommentKey];

    }

    returnself;

}

-(id)copyWithZone:(NSZone *)zone

{

    Payout*copy=[[[selfclass]allocWithZone:zone]init];

    copy.amount=amount;

    copy.time=[self.timecopyWithZone:zone];

    copy.type=[self.typecopyWithZone:zone];

    copy.comment=[self.commentcopyWithZone:zone];

    return copy;

}

-(NSString*)setMoth:(NSDate*)datetime

{

    //datetime= self.time;

    NSDateFormatter*atime=[[NSDateFormatteralloc]init];

    [atime setDateStyle:NSDateFormatterMediumStyle];

    [atime setTimeStyle:NSDateFormatterShortStyle];

    [atime setDateFormat:@"MM"];

    NSString*moth=[atimestringFromDate:self.time];

   return moth;

}

@end  

Cada variable miembro de esta clase sigue el protocolo <NSCoping>. ¿Por qué implementar este acuerdo? Debido a que escribimos datos en archivos, el asunto es un proceso de copia que debe llevarse a cabo. Queremos copiar un dato. Los dos datos después de la copia no se afectan entre sí. Son un clon independiente. Cuando se modifican los datos de una copia, los datos de la otra copia no se afectarán entre sí. Esta necesidad de lograr el protocolo <NSCopying> :( el id mencionado anteriormente ) copyWithZone :( NSZone  *) Método de zona o acuerdo <NSMutableCopying> :( el id mencionado anteriormente ) mutableCopyWithZone :( NSZone  *) Zone. El siguiente paso es escribir los datos en un archivo y almacenarlos en la zona de pruebas de la aplicación. Primero, debe haber una ruta para almacenar los datos El método para obtener la ruta es el siguiente.

#define KFilenme @ "aehive"

- ( NSString *) dataFilepath

{

    NSArray * rutas = NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES );

    NSString * documentDirectory = [rutas objectAtIndex : 0];

    return [documentDirectorystringByAppendingPathComponent:KFilenme];

}

接着我们就是要有两个最重要的方法来进行文件的读写操作。我就直接上代码了。

-(void) writeList:(NSMutableArray *) list To:(NSString *) fileName//写的函数

{

    NSMutableData*data=[[NSMutableDataalloc]init];//声明一个可变数据类型

    NSKeyedArchiver*archiver=[[NSKeyedArchiveralloc]initForWritingWithMutableData:data];//编码

    [archiver encodeObject:listforKey:KDataKey];//存放数据文件的类型和名字

    [archiver finishEncoding];//编码完成

    [data writeToFile:[selfdataFilepath]atomically:YES];//写在相应的路径下

}

-(NSMutableArray *) readListFromFile:(NSString *) fileName//读的函数

{

    if ([[NSFileManagerdefaultManager]fileExistsAtPath:fileName])//是否存在要读的数据类型,如果存在

    {

        NSData*data=[[NSMutableDataalloc]initWithContentsOfFile:fileName];//打开名为fileName数据类型的数据

       NSKeyedUnarchiver*unarchiver=[[NSKeyedUnarchiveralloc]initForReadingWithData:data];//解码

        NSMutableArray * array = [unarchiverdecodeObjectForKey:KDataKey];//把解码出来的数据存放在可变数组里面

        [unarchiver finishDecoding];//解码完成

        if (!array) {

            array=[[NSMutableArrayalloc]init];

        }

        return array;//返回该数组

    }

    

    return [[NSMutableArrayalloc]init];;//如果不存在名为fileName数据类型直接返回空

}

可以看出这种把数据写到文件中,其实就是利用NSKeyedArchiver归档(将各种类型的对象存到文件中) ,编码后直接调用- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;写到文件中就可以了。读出来的时候也是调用相应的函数读出来,然后解码。这个存进去的数据就可以完全读出来了。写到这里,可能大家会认为关于文件的读写就完了。其实今天的重点还没有开始。

我们在iOS中NSKeyedArchiver方法来归档数据。数据的读写相对容易得多了。有时候我们拿到的文件是其它平台把一个已经定义好了的结构体等数据以二进制的方式存放到文件中。问题就来了这时候怎么读数据呢?其实这时候我们就要用到下面的方法来对数据进行读的操作。这些数据存储空间里面是有相应的长度的,我们知道了该结构体的定义,就可以知道该结构体的长度,然后就可以把这些数据一个字节一个字节的拷贝出来。这需要我们iOS端有与之相应的结构体。下面这段代码就是对一份文件中存了很多个相同结构的结构数据拷贝出来。大概思想就是我们做了一个循环来读每一个结构体的数据,只要拷贝的总字节小于文件的总字节数。就说明这个数据还没有读到末尾。还用了一个变量来纪录目前读过的总字节数。具体代码如下。

NSString *path = [[NSBundlemain Bundle]pathForResource:@"n9gps"ofType:@"rbb"];

//获取数据

NSData *reader = [NSDatadata WithContentsOfFile:path];

//得到文件的长度(大小)

NSInteger nSize = [reader length];

NSInteger nPos =0;

NSMutableDictionary*dataDic=[[NSMutableDictionaryalloc]init];

char* pBuffer = [readerbytes];

while (nPos<nSize) {

structRMBDM_FRAMEHEADER frameHeader={0};

memcpy(&frameHeader, pBuffer+nPos,sizeof(RMBDM_FRAMEHEADER));

nPos += sizeof(RMBDM_FRAMEHEADER);

structRMBDM_DATETIME dataTime={0};

structRMBDM_GPS dataGps={0};

memcpy(&dataTime, pBuffer+nPos,sizeof(RMBDM_DATETIME));

nPos += sizeof(RMBDM_DATETIME);

memcpy(&dataGps, pBuffer+nPos,sizeof(RMBDM_GPS));

nPos += sizeof(RMBDM_GPS);

NSString*time=[NSStringstringWithFormat:@"%d-%d-%d %d:%d:%d",dataTime.stuDateTime.cYear,dataTime.stuDateTime.cMonth,dataTime.stuDateTime.cDay,dataTime.stuDateTime.cHour,dataTime.stuDateTime.cMinute,dataTime.stuDateTime.cSecond];

N9MRmdbGpsInfo* rmdbGpsInfo=[[N9MRmdbGpsInfoalloc]init];

rmdbGpsInfo.cVersion=[NSStringstringWithFormat:@"%d",dataGps.cVersion];

rmdbGpsInfo.cGpsSource=[NSStringstringWithFormat:@"%d",dataGps.cGpsSource];

rmdbGpsInfo.reserved1=[NSStringstringWithFormat:@"%d",dataGps.reserved1];

rmdbGpsInfo.cGpsStatus=[NSStringstringWithFormat:@"%d",dataGps.cGpsStatus];

rmdbGpsInfo.cSpeedUnit=[NSStringstringWithFormat:@"%d",dataGps.cSpeedUnit];

rmdbGpsInfo.usSpeed=dataGps.usSpeed;

rmdbGpsInfo.cDirectionLatitude=[NSStringstringWithFormat:@"%d",dataGps.cDirectionLatitude];

rmdbGpsInfo.cDirectionLongitude=[NSStringstringWithFormat:@"%d",dataGps.cDirectionLongitude];

rmdbGpsInfo.cLongitudeCent=[NSStringstringWithFormat:@"%d",dataGps.cLongitudeCent];

rmdbGpsInfo.lLatitudeSec=dataGps.lLatitudeSec;

rmdbGpsInfo.lLongitudeSec=dataGps.lLongitudeSec;

rmdbGpsInfo.usGpsAngle=dataGps.usGpsAngle;

rmdbGpsInfo.cGpPlanetNum=[NSStringstringWithFormat:@"%d",dataGps.cGpPlanetNum];

rmdbGpsInfo.cBdPlanetNum=[NSStringstringWithFormat:@"%d",dataGps.cBdPlanetNum];

rmdbGpsInfo.cSignalStrength=[NSStringstringWithFormat : @ "% d" , dataGps. cSignalStrength ];

[dataDic  setObject : rmdbGpsInfo forKey : tiempo];

}

Supongo que te gusta

Origin blog.csdn.net/qq_27740983/article/details/51258943
Recomendado
Clasificación