DDFileReader.h
@interface Ddfilereader:nsobject {NSString * filePath;
Nsfilehandle * FILEHANDLE;
unsigned long long currentoffset;
unsigned long long totalfilelength;
NSString * Linedelimiter;
Nsuinteger chunksize;
} @property (nonatomic, copy) NSString * linedelimiter;
@property (nonatomic) Nsuinteger chunksize;
-(ID) Initwithfilepath: (NSString *) Apath;
-(NSString *) readLine;
-(NSString *) readtrimmedline;
#if ns_blocks_available-(void) Enumeratelinesusingblock: (void (^) (nsstring*, BOOL *)) block; #endif @end//ddfilereader.m #import "DDFileReader.h" @interface NSData (ddadditions)-(Nsrange) Rangeofdata_dd: (NS
Data *) Datatofind; @end @implementation NSData (ddadditions)-(Nsrange) RANGEOFDATA_DD: (NSData *) datatofind {const void * bytes = [s
Elf bytes];
Nsuinteger length = [self length];
const void * searchbytes = [Datatofind bytes];
Nsuinteger searchlength = [Datatofind length];
Nsuinteger searchindex = 0; Nsrange Foundrange= {nsnotfound, searchlength}; for (Nsuinteger index = 0; index < length; index++) {if ((char *) bytes) [Index] = = ((char *) searchbytes) [Searc
Hindex]) {//the current character matches if (foundrange.location = = Nsnotfound) {
foundrange.location = index;
} searchindex++;
if (Searchindex >= searchlength) {return foundrange;}
else {searchindex = 0;
Foundrange.location = Nsnotfound;
} return Foundrange;
@end @implementation ddfilereader @synthesize linedelimiter, chunksize; -(ID) Initwithfilepath: (NSString *) Apath {if (self = [super init]) {filehandle = [Nsfilehandle filehandlefo
Rreadingatpath:apath];
if (FileHandle = = nil) {[Self release]; return nil;
} linedelimiter = [[NSString alloc] initwithstring:@ "\ n"];
[FileHandle retain];
FilePath = [Apath retain]; CurreNtoffset = 0ULL;
Chunksize = 10;
[FileHandle Seektoendoffile];
Totalfilelength = [FileHandle offsetinfile];
We don ' t need to seek the back, since ReadLine'll do.
return self;
}-(void) Dealloc {[FileHandle closefile];
[FileHandle release], filehandle = nil;
[FilePath release], FilePath = nil;
[Linedelimiter release], linedelimiter = nil;
Currentoffset = 0ULL;
[Super Dealloc];
}-(NSString *) ReadLine {if (currentoffset >= totalfilelength) {return nil;}
NSData * Newlinedata = [Linedelimiter datausingencoding:nsutf8stringencoding];
[FileHandle Seektofileoffset:currentoffset];
Nsmutabledata * CurrentData = [[Nsmutabledata alloc] init];
BOOL Shouldreadmore = YES;
NSAutoreleasePool * Readpool = [[NSAutoreleasePool alloc] init];
while (Shouldreadmore) {if (Currentoffset >= totalfilelength) {break;}
NSData * chunk = [FileHandle readdataoflength:chunksize]; Nsrange Newlinerange = [Chunk rangeofdata_dd:newlinedata];
if (newlinerange.location!= nsnotfound) {//include The length so we can include the delimiter in the string
chunk = [Chunk subdatawithrange:nsmakerange (0, Newlinerange.location+[newlinedata length])];
Shouldreadmore = NO;
} [CurrentData Appenddata:chunk];
Currentoffset + = [chunk length];
[Readpool release];
NSString * line = [[NSString alloc] Initwithdata:currentdata encoding:nsutf8stringencoding];
[CurrentData release];
return [line autorelease]; }-(NSString *) readtrimmedline {return [[self readLine] stringbytrimmingcharactersinset:[nscharacterset whitespace
Andnewlinecharacterset]];
#if ns_blocks_available-(void) Enumeratelinesusingblock: (void (^) (nsstring*, bool*)) block {NSString * line = nil;
BOOL stop = NO;
while (stop = NO && (line = [self readLine])) {Blocks (line, &stop); }} #endif @end If Your file is small, then @mipadi ' s method would probably be just fine. However, if your file is large (> 1MB, perhaps?), then your may want to consider reading the file line-by-line. I wrote a class once to did that, which I ' ll paste here://ddfilereader.h @interface ddfilereader:nsobject {Nsstrin
G * FILEPATH;
Nsfilehandle * FILEHANDLE;
unsigned long long currentoffset;
unsigned long long totalfilelength;
NSString * Linedelimiter;
Nsuinteger chunksize;
} @property (nonatomic, copy) NSString * linedelimiter;
@property (nonatomic) Nsuinteger chunksize;
-(ID) Initwithfilepath: (NSString *) Apath;
-(NSString *) readLine;
-(NSString *) readtrimmedline;
#if ns_blocks_available-(void) Enumeratelinesusingblock: (void (^) (nsstring*, BOOL *)) block; #endif @end//ddfilereader.m #import "DDFileReader.h" @interface NSData (ddadditions)-(Nsrange) Rangeofdata_dd: (NS
Data *) Datatofind; @end @implementation NSData (ddadditions)-(Nsrange) Rangeofdata_DD: (NSData *) datatofind {const void * bytes = [self bytes];
Nsuinteger length = [self length];
const void * searchbytes = [Datatofind bytes];
Nsuinteger searchlength = [Datatofind length];
Nsuinteger searchindex = 0;
Nsrange Foundrange = {nsnotfound, searchlength}; for (Nsuinteger index = 0; index < length; index++) {if ((char *) bytes) [Index] = = ((char *) searchbytes) [Searc
Hindex]) {//the current character matches if (foundrange.location = = Nsnotfound) {
foundrange.location = index;
} searchindex++;
if (Searchindex >= searchlength) {return foundrange;}
else {searchindex = 0;
Foundrange.location = Nsnotfound;
} return Foundrange;
@end @implementation ddfilereader @synthesize linedelimiter, chunksize; -(ID) Initwithfilepath: (NSString *) Apath {if (self = [super init]) {filehandle = [NsfilehandLe Filehandleforreadingatpath:apath];
if (FileHandle = = nil) {[Self release]; return nil;
} linedelimiter = [[NSString alloc] initwithstring:@ "\ n"];
[FileHandle retain];
FilePath = [Apath retain];
Currentoffset = 0ULL;
Chunksize = 10;
[FileHandle Seektoendoffile];
Totalfilelength = [FileHandle offsetinfile];
We don ' t need to seek the back, since ReadLine'll do.
return self;
}-(void) Dealloc {[FileHandle closefile];
[FileHandle release], filehandle = nil;
[FilePath release], FilePath = nil;
[Linedelimiter release], linedelimiter = nil;
Currentoffset = 0ULL;
[Super Dealloc];
}-(NSString *) ReadLine {if (currentoffset >= totalfilelength) {return nil;}
NSData * Newlinedata = [Linedelimiter datausingencoding:nsutf8stringencoding];
[FileHandle Seektofileoffset:currentoffset]; Nsmutabledata * CurrentData = [[Nsmutabledata alloc] IniT];
BOOL Shouldreadmore = YES;
NSAutoreleasePool * Readpool = [[NSAutoreleasePool alloc] init];
while (Shouldreadmore) {if (Currentoffset >= totalfilelength) {break;}
NSData * chunk = [FileHandle readdataoflength:chunksize];
Nsrange Newlinerange = [Chunk rangeofdata_dd:newlinedata];
if (newlinerange.location!= nsnotfound) {//include The length so we can include the delimiter in the string
chunk = [Chunk subdatawithrange:nsmakerange (0, Newlinerange.location+[newlinedata length])];
Shouldreadmore = NO;
} [CurrentData Appenddata:chunk];
Currentoffset + = [chunk length];
[Readpool release];
NSString * line = [[NSString alloc] Initwithdata:currentdata encoding:nsutf8stringencoding];
[CurrentData release];
return [line autorelease]; }-(NSString *) readtrimmedline {return [[self readLine] stringbytrimmingcharactersinset:[nscharacterset whitespace AndneWlinecharacterset]];
#if ns_blocks_available-(void) Enumeratelinesusingblock: (void (^) (nsstring*, bool*)) block {NSString * line = nil;
BOOL stop = NO;
while (stop = NO && (line = [self readLine])) {Blocks (line, &stop); }} #endif @end
|
Then to use this, and you ' d do: Ddfilereader * reader = [[Ddfilereader alloc] initwithfilepath:pathtomyfile];
NSString * line = nil;
while (line = [reader readLine])) {
NSLog (@ ' read line:%@ ', line);
}
[Reader release];
Or (for 10.6+ and IOS 4+):
ddfilereader * reader = [[Ddfilereader alloc] initwithfilepath:pathtomyfile];
[Reader enumeratelinesusingblock:^ (NSString * line, BOOL * stop) {
NSLog (@ ' read line:%@ ', line);
}];
[Reader release];
|
Http://stackoverflow.com/questions/3707427/how-to-read-data-from-nsfilehandle-line-by-line?lq=1