在逗号分隔值文件中搜索值
Posted
技术标签:
【中文标题】在逗号分隔值文件中搜索值【英文标题】:Search a value in a comma separated value file 【发布时间】:2012-12-18 13:08:17 【问题描述】:您好,我已经实现了以下在 csv 文件中搜索值的方法:
- (void)recordsForValue:(NSString*)searchedValue
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSError* err;
NSString *csvFilePath = //path of csv file
NSString *csvString = nil;
csvString = [[NSString alloc]initWithContentsOfFile:csvFilePath encoding:NSASCIIStringEncoding error:&err];
csvFilePath = nil;
NSRange searchRange = NSMakeRange(0,csvString.length);
NSRange foundRange;
int i=0;
locationRecordsArray = [NSMutableArray array];
while (searchRange.location <= csvString.length)
NSString *sFinalResult = nil;
searchRange.length = csvString.length-searchRange.location;
foundRange = [csvString rangeOfString:searchedValue options:NSCaseInsensitiveSearch range:searchRange];
if (foundRange.location != NSNotFound)
i++;
NSRange endDivRange;
NSRange startRange;
endDivRange.location = foundRange.length + foundRange.location;
endDivRange.length = [csvString length] - endDivRange.location;
endDivRange = [csvString rangeOfString:@"\n" options:NSCaseInsensitiveSearch range:endDivRange];
if (endDivRange.location != NSNotFound)
// Tags found: retrieve string between them
foundRange.location += foundRange.length;
foundRange.length = endDivRange.location - foundRange.location;
startRange.location = 0;
startRange.length = foundRange.location;
NSString* sTemp = nil;
sTemp = [[NSString alloc]initWithString:[csvString substringWithRange:startRange]];
startRange = [sTemp rangeOfString:@"\n" options:NSBackwardsSearch range:startRange];
[sTemp release];
if (startRange.location != NSNotFound)
// Tags found: retrieve string between them
foundRange.location = startRange.location;
foundRange.length = endDivRange.location - foundRange.location;
sFinalResult = nil;
sFinalResult = [[NSString alloc]initWithString:[csvString substringWithRange:foundRange]];
if(sFinalResult != nil)
[locationRecordsArray addObject:sFinalResult];
[sFinalResult release];
// found an occurrence of the substring! do stuff here
searchRange.location = foundRange.location+foundRange.length;
else
// no more substring to find
break;
[csvString release];
[self insertLocationRecordsInDatabase]; // insert records of locationArray
[self performSelectorOnMainThread:@selector(showScanningView) withObject:nil waitUntilDone:NO];
[pool drain];
1.上述方法是在单独的线程中调用的,所以我们必须在单独的自动释放池中处理。
2. The 'searchedValue' is a value to be searched in the CSV file string.
3. Whenever we get a location for the value searched in the csvString, we add the complete line of string in an array.The line
is extracted by searching for newline (i.e \n) character.
4. This code is running fine if the length of csvString is small. But in case of a very large csvString, the app is crashing with low
memory warning. I checked in Instruments. The problem is with some
String variable which is reaching the size of 100s of MB and the app
is closing because of low memory.But I am not able to solve how to
optimise the memory of my string variables.Please give some
solution.
【问题讨论】:
【参考方案1】:我的问题终于解决了!! 我使用以下代码来优化内存:
- (void)recordsForLocationValue:(NSString*) searchedValue
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSError* err;
NSString *csvFilePath = //path of csv file
NSMutableString *csvString = [NSMutableString stringWithContentsOfFile:csvFilePath encoding:NSASCIIStringEncoding error:&err];
csvFilePath = nil;
NSRange searchRange = NSMakeRange(0,csvString.length);
NSRange foundRange;
int i=0;
NSString* sTemp = nil;
locationRecordsArray = [[NSMutableArray alloc]init];
while ([csvString length] > 1)
searchRange.length = csvString.length-searchRange.location;
foundRange = [csvString rangeOfString: searchedValue
options:NSCaseInsensitiveSearch range:searchRange];
if (foundRange.location != NSNotFound)
i++;
NSRange endDivRange;
NSRange startRange;
endDivRange.location = foundRange.length + foundRange.location;
endDivRange.length = [csvString length] - endDivRange.location;
endDivRange = [csvString rangeOfString:@"\n" options:NSCaseInsensitiveSearch range:endDivRange];
if (endDivRange.location != NSNotFound)
// Tags found: retrieve string between them
foundRange.location += foundRange.length;
foundRange.length = endDivRange.location - foundRange.location;
startRange.location = 0;
startRange.length = foundRange.location;
sTemp = [csvString substringWithRange:startRange];
startRange = [sTemp rangeOfString:@"\n" options:NSBackwardsSearch range:startRange];
if (startRange.location != NSNotFound)
// Tags found: retrieve string between them
foundRange.location = startRange.location;
foundRange.length = endDivRange.location - foundRange.location;
sTemp = [csvString substringWithRange:foundRange];
if(sTemp != nil)
[locationRecordsArray addObject:sTemp];
// found an occurrence of the substring! do stuff here
searchRange.location = foundRange.location+foundRange.length;
[csvString deleteCharactersInRange:NSMakeRange(0, searchRange.location-1)];
searchRange.location = 0;
else
NSLog(@"no more substring to find");
// no more substring to find
break;
[self insertLocationRecordsInDatabase];
[self performSelectorOnMainThread:@selector(showScanningView) withObject:nil waitUntilDone:NO];
[pool drain];
[NSThread exit];
【讨论】:
很好的解决方案,但根据内存优化不是最好的:)【参考方案2】:使用内存映射,这样您就不必一次加载所有内容。请参阅:Substitute for NSData deprecated dataWithContentsOfMappedFile
或
将文件分成几个小文件
【讨论】:
以上是关于在逗号分隔值文件中搜索值的主要内容,如果未能解决你的问题,请参考以下文章