OneManBand
OneManBand

Reputation: 558

CHCSVParser returns nil Array for valid filePath & valid csv file

I am trying to parse a .csv file with approximately 30K lines. The following was mycode:

NSString *pathToGameLibrary = [[NSBundle mainBundle] pathForResource:@"GameLibrarySample" ofType:@"csv"];
NSArray *gameLibraryData = [NSArray arrayWithContentsOfCSVFile:pathToGameLibrary];

At the end of this execution, gameLibraryData is nil.

I can confirm that both the path and the csv file are valid because the following code spits out 30,000 lines of data to the console:

NSString *pathToGameLibrary = [[NSBundle mainBundle] pathForResource:@"GameLibrarySample" ofType:@"csv"];
NSString *fileString = [NSString stringWithContentsOfFile:pathToGameLibrary encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@", fileString);

Because this code does not work, I assume that the failure has to do with the length of the csv file. In an earlier question, CHCSV's author Dave DeLong suggests that:

"If this is a very big file, then you'll want to alloc/init a CHCSVParser with the path to the local copy of the CSV file."

So...I've tried to follow what the original poster attempted with this code:

NSString *pathToGameLibrary = [[NSBundle mainBundle] pathForResource:@"GameLibrarySample" ofType:@"csv"];
CHCSVParser *file = [[CHCSVParser alloc] initWithContentsOfCSVFile:pathToGameLibrary];
[file setDelegate:self];

At which point the method callbacks which enable retrieval of data are:

- (void)parserDidBeginDocument:(CHCSVParser *)parser;
- (void)parserDidEndDocument:(CHCSVParser *)parser;
- (void)parser:(CHCSVParser *)parser didBeginLine:(NSUInteger)recordNumber;
- (void)parser:(CHCSVParser *)parser didEndLine:(NSUInteger)recordNumber;
- (void)parser:(CHCSVParser *)parser didReadField:(NSString *)field atIndex:(NSInteger)fieldIndex;
- (void)parser:(CHCSVParser *)parser didReadComment:(NSString *)comment;
- (void)parser:(CHCSVParser *)parser didFailWithError:(NSError *)error;

Thanks to yonosoytu for le assistance.

On Topic Post-Edit Question: So what counts as a "very big file" anyway? At which point is it prudent to use delegation over the simple 'arrayWithContentsofCSVFile'?

Upvotes: 0

Views: 581

Answers (1)

lxt
lxt

Reputation: 31304

So what counts as a "very big file" anyway? At which point is it prudent to use delegation over the simple 'arrayWithContentsofCSVFile'?

The way that CHCSVParser reads and parses your CSV file is identical regardless of whether you're using the NSArray category method or directly interfacing with the delegate itself (you can see this for yourself here). So "a very big file" is really a CSV file which would be too large to hold in memory as an NSArray in its entirety. The memory consumption will depend both on the number of columns and the number of rows, so it's hard to give a definite limit.

What this means is that the problems you get from using the -arrayWithContentsOfCSV with large files shouldn't manifest themselves as returning nil, but as low memory warnings and the like. The fact you're getting nil returned suggests something else is going on.

Firstly, you say you've tried logging the file, so you know it exists - have you tried parsing a much smaller subset of that file? The problem might be that your CSV is badly formed. Or alternatively - and this is something I've had problems with myself when working with CSV on iOS - is your CSV encoded correctly? Sometimes if you're outputting directly from Excel you can end up with strange and weird text encodings that occasionally seem to break things.

You can always breakpoint and step-through the parsing methods in CHCSVParser for yourself and see what's going on. I hope this is of some use to you. As you've discovered, Dave DeLong actually posts here quite a bit - if you're lucky he'll probably come along and share more wisdom than I can.

Upvotes: 1

Related Questions