Created
December 17, 2013 06:18
-
-
Save yaozhuoyu/8000847 to your computer and use it in GitHub Desktop.
实现一行一行的读文件
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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; | |
- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL *))block; | |
@end | |
@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; | |
- (void) dealloc { | |
[fileHandle closeFile]; | |
currentOffset = 0ULL; | |
} | |
- (id) initWithFilePath:(NSString *)aPath { | |
if (self = [super init]) { | |
fileHandle = [NSFileHandle fileHandleForReadingAtPath:aPath]; | |
lineDelimiter = @"\n"; | |
filePath = aPath; | |
currentOffset = 0ULL; | |
chunkSize = 128; | |
totalFileLength = [fileHandle seekToEndOfFile]; | |
//totalFileLength = [fileHandle offsetInFile]; | |
//we don't need to seek back, since readLine will do that. | |
} | |
return self; | |
} | |
- (NSString *) readLine { | |
if (currentOffset >= totalFileLength) { return nil; } | |
NSData * newLineData = [lineDelimiter dataUsingEncoding:NSUTF8StringEncoding]; | |
[fileHandle seekToFileOffset:currentOffset]; | |
NSMutableData * currentData = [[NSMutableData alloc] init]; | |
BOOL shouldReadMore = YES; | |
@autoreleasepool { | |
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]; | |
} | |
} | |
NSString * line = [[NSString alloc] initWithData:currentData encoding:NSUTF8StringEncoding]; | |
return line; | |
} | |
- (NSString *) readTrimmedLine { | |
return [[self readLine] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; | |
} | |
- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL*))block { | |
NSString * line = nil; | |
BOOL stop = NO; | |
while (stop == NO && (line = [self readLine])) { | |
block(line, &stop); | |
} | |
} | |
@end | |
//使用 | |
- (void)readFile:(NSString *)pathToMyFile{ | |
DDFileReader * reader = [[DDFileReader alloc] initWithFilePath:pathToMyFile]; | |
[reader enumerateLinesUsingBlock:^(NSString * line, BOOL * stop) { | |
NSLog(@"read line: %@", line); | |
}]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment