0

我正在尝试解析大约 30K 行的 .csv 文件。以下是我的代码:

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

在此执行结束时,gameLibraryData 为 nil。

我可以确认路径和 csv 文件都是有效的,因为以下代码向控制台输出了 30,000 行数据:

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

因为这段代码不起作用,我认为失败与 csv 文件的长度有关。在较早的问题中,CHCSV 的作者 Dave DeLong 建议:

“如果这是一个非常大的文件,那么您需要分配/初始化一个带有 CSV 文件本地副本路径的 CHCSVParser。”

所以......我试图遵循原始海报尝试使用此代码的内容:

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

此时启用数据检索的方法回调是:

- (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;

感谢 yonosoytu 的帮助。

关于主题编辑后的问题:那么什么算作“非常大的文件”呢?在什么时候使用简单的“arrayWithContentsofCSVFile”委托是谨慎的?

4

1 回答 1

1

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.

于 2013-06-19T22:38:49.207 回答