如何从 NSFileHandle 逐行读取数据?

编程入门 行业动态 更新时间:2024-10-25 18:23:23
本文介绍了如何从 NSFileHandle 逐行读取数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个包含给定数据的文本文件

例如

PUFGUjVRallYZDNaazFtVjVObU1zWm5ZcUJUYU5ORk4zbGthNHNDVUdSMlFVQmpSVEoxUUNSallYaFhkanBITXBGR1NTQnpZRTltZE1OalVzSkdXQ0Z6WXR0V2RpTmpTdXgwTWs5V1lZSkZiWjFXT29OV2JSVlhaSTUwYUpwR040UUZXTzVHVXFoWFVRcFdWNHdVTUJ0Q1VHSmxXVlJVTlJCMVE1VTFWVPUFGUjVRallYZDNaazFtVjVObU1zWm5ZcUJUYU5ORk4zbGthNHNDVUdSMlFVQmpSVEoxUUNSallYaFhkanBITXBGR1NTQnpZRTltZE1OalVzSkdXQ0Z6WXR0V2RpTmpTdXgwTWs5V1lZSkZiWjFXT29OV2JSVlhaSTUwYUpwR040UUZXTzVHVXFoWFVRcFdWNHdVTUJ0Q1VHSmxXVlJVTlJCMVE1VTFWV

现在我想逐行读取数据.这意味着首先我要阅读

PUFGUjVRallYZDNaazFtVjVObU1zWm5ZcUJUYU5ORk4zbGthNHNDVUdSMlFVQmpSVEoxUUNSallYaFhkanBITXBGR1NTQnpZRTltZE1OalVzSkdXQ0Z6WXR0V2RpTmpTdXgwTWs5V1lZSkZiWjFXT29OV2JSVlhaSTUwYUpwR040UUZXTzVHVXFoWFVRcFdWNHdVTUJ0Q1VHSmxXVlJVTlJCMVE1VTFWV

然后剩下的.有人知道吗??

解决方案

如果您的文件很小,那么@mipadi 的方法可能会很好.但是,如果您的文件很大(可能大于 1MB?),那么您可能需要考虑逐行读取文件.我曾经写过一个类来做到这一点,我将粘贴在这里:

//DDFileReader.h@interface DDFileReader : NSObject {NSString * 文件路径;NSFileHandle * 文件句柄;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 *) 读行;- (NSString *) readTrimmedLine;#if NS_BLOCKS_AVAILABLE- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL *))block;#万一@结尾//DDFileReader.m#import "DDFileReader.h";@interface NSData (DDAdditions)- (NSRange) rangeOfData_dd:(NSData *)dataToFind;@结尾@implementation NSData (DDAdditions)- (NSRange) rangeOfData_dd:(NSData *)dataToFind {const void * bytes = [self bytes];NSUInteger 长度 = [自身长度];const void * searchBytes = [dataToFind bytes];NSUInteger searchLength = [dataToFind length];NSUInteger searchIndex = 0;NSRange foundRange = {NSNotFound, searchLength};for (NSUInteger index = 0; index = totalFileLength) { return nil;}NSData * newLineData = [lineDelimiter dataUsingEncoding:NSUTF8StringEncoding];[fileHandle seekToFileOffset:currentOffset];NSMutableData * currentData = [[NSMutableData alloc] init];BOOL shouldReadMore = YES;NSAutoreleasePool * readPool = [[NSAutoreleasePool alloc] init];而(应该阅读更多){if (currentOffset >= totalFileLength) { break;}NSData * chunk = [fileHandle readDataOfLength:chunkSize];NSRange newLineRange = [chunk rangeOfData_dd:newLineData];如果(newLineRange.location != NSNotFound){//包含长度,以便我们可以在字符串中包含分隔符chunk = [chunk subdataWithRange:NSMakeRange(0, newLineRange.location+[newLineData length])];应该阅读更多 = 否;}[currentData appendData:chunk];currentOffset += [块长度];}[readPool 发布];NSString * line = [[NSString alloc] initWithData:currentData encoding:NSUTF8StringEncoding];[当前数据发布];返回 [行自动释放];}- (NSString *) readTrimmedLine {返回 [[self readLine] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];}#if NS_BLOCKS_AVAILABLE- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL*))block {NSString * line = nil;布尔停止 = 否;while (stop == NO && (line = [self readLine])) {块(线,&停止);}}#万一@结尾

然后要使用它,您可以:

DDFileReader * reader = [[DDFileReader alloc] initWithFilePath:pathToMyFile];NSString * line = nil;while ((line = [reader readLine])) {NSLog(@"读取行:%@", line);}[读者发布];

或(适用于 10.6+ 和 iOS 4+):

DDFileReader * reader = [[DDFileReader alloc] initWithFilePath:pathToMyFile];[reader enumerateLinesUsingBlock:^(NSString * line, BOOL * stop) {NSLog(@"读取行:%@", line);}];[读者发布];

I have a text file having data as given

e.g.

PUFGUjVRallYZDNaazFtVjVObU1zWm5ZcUJUYU5ORk4zbGthNHNDVUdSMlFVQmpSVEoxUUNSallYaFhkanBITXBGR1NTQnpZRTltZE1OalVzSkdXQ0Z6WXR0V2RpTmpTdXgwTWs5V1lZSkZiWjFXT29OV2JSVlhaSTUwYUpwR040UUZXTzVHVXFoWFVRcFdWNHdVTUJ0Q1VHSmxXVlJVTlJCMVE1VTFWV PUFGUjVRallYZDNaazFtVjVObU1zWm5ZcUJUYU5ORk4zbGthNHNDVUdSMlFVQmpSVEoxUUNSallYaFhkanBITXBGR1NTQnpZRTltZE1OalVzSkdXQ0Z6WXR0V2RpTmpTdXgwTWs5V1lZSkZiWjFXT29OV2JSVlhaSTUwYUpwR040UUZXTzVHVXFoWFVRcFdWNHdVTUJ0Q1VHSmxXVlJVTlJCMVE1VTFWV

Now I want to read data line by line. That means first I want to read

PUFGUjVRallYZDNaazFtVjVObU1zWm5ZcUJUYU5ORk4zbGthNHNDVUdSMlFVQmpSVEoxUUNSallYaFhkanBITXBGR1NTQnpZRTltZE1OalVzSkdXQ0Z6WXR0V2RpTmpTdXgwTWs5V1lZSkZiWjFXT29OV2JSVlhaSTUwYUpwR040UUZXTzVHVXFoWFVRcFdWNHdVTUJ0Q1VHSmxXVlJVTlJCMVE1VTFWV

and then next remaining. anyone have any idea??

解决方案

If your file is small, then @mipadi's method will probably be just fine. However, if your file is large (> 1MB, perhaps?), then you may want to consider reading the file line-by-line. I wrote a class once to do that, which I'll paste here:

//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:(NSData *)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)[searchIndex]) { //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:@" "]; [fileHandle retain]; filePath = [aPath retain]; currentOffset = 0ULL; chunkSize = 10; [fileHandle seekToEndOfFile]; totalFileLength = [fileHandle offsetInFile]; //we don't need to seek back, since readLine will do that. } 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 whitespaceAndNewlineCharacterSet]]; } #if NS_BLOCKS_AVAILABLE - (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL*))block { NSString * line = nil; BOOL stop = NO; while (stop == NO && (line = [self readLine])) { block(line, &stop); } } #endif @end

Then to use this, 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];

更多推荐

如何从 NSFileHandle 逐行读取数据?

本文发布于:2023-07-06 07:54:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1047559.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据   NSFileHandle

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!