说我有像这样的文本文件my.txt
this is line 1
this is line 2
....
this is line 999999
this is line 1000000
在Unix中,我可以通过发出“head -1000 my.txt | tail -1”之类的命令获得“this is line 1000”的行。在Objective-C中获得此功能的相应方法是什么?
答案 0 :(得分:3)
如果将整个事物同时存储在内存中并不是太低效,那么最紧凑的调用序列(我已经扩展到多行以便简化说明)将是:
NSError *error = nil;
NSString *sourceString = [NSString stringWithContentsOfFile:@"..."
encoding:NSUTF8StringEncoding error:&error];
NSArray *lines = [sourceString componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
NSString *relevantLine = [lines objectAtIndex:1000];
您应该检查error
的值和count
的{{1}}进行验证。
lines
)。
\r\n
可能是你需要处理的内容,如果内存占用是一个问题,它几乎没有比C的stdio.h fopen / fread / etc更进化,所以你将不得不写下你自己的小循环来突破。
答案 1 :(得分:2)
答案并未解释如何读取文件 LARGE 以保留在内存中。 Objective-C中没有很好的解决方案来读取大文本文件而不将它们放入内存(这不是一个选项)。
在这些情况下,我喜欢使用c方法:
FILE* file = fopen("path to my file", "r");
size_t length;
char *cLine = fgetln(file,&length);
while (length>0) {
char str[length+1];
strncpy(str, cLine, length);
str[length] = '\0';
NSString *line = [NSString stringWithFormat:@"%s",str];
% Do what you want here.
cLine = fgetln(file,&length);
}
请注意,fgetln不会保留换行符。另外,我们+1为str的长度,因为我们想为NULL终止腾出空间。
答案 2 :(得分:1)
最简单的方法是使用一个NSString文件方法加载文件,然后使用 - [NSString componentsSeparatedByString:]方法获取每一行的数组。
或者您可以使用NSScanner,扫描新行/回车字符,直到您到达感兴趣的行。
如果您真的关心内存使用情况,可以查看NSInputStream使用它来读取文件,保留新行数。令人遗憾的是,NSScanner无法使用NSInputStream。
答案 3 :(得分:1)
我不认为这是完全重复的,因为听起来你想跳过文件中的某些行,但是你可以轻松地使用像这样的方法:
Objective-C: Reading a file line by line(Specific answer有一些示例代码)
循环输入文件,读入一大块数据,并查找换行符。计算它们,当你找到正确的数字时,输出数据后直到下一个数据。
您的示例看起来可能有数十万行,所以绝对不要只是将文件读入NSString,并且绝对不会将其转换为NSArray。
如果你想以更高级的NSInputStream方式(在字符集解码中具有一些关键优势)这样做,这里有一个很好的例子,它显示了轮询使用来自流源的所有数据的基本思想(在文件示例,它有点矫枉过正)。它用于输出,但输入的想法也很好: Polling versus Run Loop Scheduling