這讓我難堪。我正在嘗試在iOS上逐行閱讀6MB CSV文件。我已經嘗試使用純C文件指針和NSInputStream輪詢,但在下面感覺最乾淨的定位。所有這三種方法都會導致看起來像讀取成功的隨機塊,但會用全部空字節填充緩衝區。我說「隨機」,但它具有一致性。在重新運行程序時,讀取在完全相同的時刻停止工作,並且讀取次數可疑(下面會詳細介紹)。異步讀取大文件導致iOS中的空塊讀取
- (id)initWithFileAtPath:(NSString *)path {
if ((self = [super init])) {
filePath = [path copy];
queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
buffer = [[NSMutableString alloc] init];
bytes = malloc(CHUNK_SIZE * sizeof(UTF8Char));
}
return self;
}
- (void)dealloc {
[filePath release];
[queue release];
[buffer release];
free(bytes);
[super dealloc];
}
- (void)stream:(NSInputStream *)stream handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventOpenCompleted:
break;
case NSStreamEventHasBytesAvailable:
[queue addOperationWithBlock:^{
[self readChunk: stream];
[self drainBuffer];
}];
break;
case NSStreamEventEndEncountered:
if ([buffer length] > 0) {
[delegate reader:self didReadLine:[NSString stringWithString:buffer]];
[buffer setString:@""];
}
[stream close];
[stream removeFromRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[stream release];
[delegate readerDidFinishReading:self];
break;
default:
NSLog(@"StreamReader: event %d", eventCode);
break;
}
}
- (void)enumerateLines {
NSInputStream *stream = [[NSInputStream alloc] initWithFileAtPath:filePath];
stream.delegate = self;
[stream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[stream open];
}
- (void)readChunk: (NSInputStream*)stream {
NSInteger readSize = [stream read:bytes maxLength:CHUNK_SIZE];
if (readSize) {
if (bytes[0] == '\0') {
NSLog(@"null buffer %d", readSize);
}
NSString *string = [[NSString alloc] initWithBytes:bytes
length:readSize
encoding:NSUTF8StringEncoding];
[buffer appendString:string];
[string release];
} else {
NSLog(@"StreamReader: read zero bytes");
}
}
- (void)drainBuffer {
static NSCharacterSet *newlines = nil;
if (newlines == nil) {
newlines = [NSCharacterSet newlineCharacterSet];
}
NSRange newlinePos;
while ((newlinePos = [buffer rangeOfCharacterFromSet:newlines]).location != NSNotFound) {
NSString *line = [buffer substringToIndex:newlinePos.location];
// remove the line from the buffer along with line separator
[buffer deleteCharactersInRange: (NSRange){0, [line length]}];
while ([buffer length] > 0 && [newlines characterIsMember:[buffer characterAtIndex:0]]) {
[buffer deleteCharactersInRange:(NSRange){0, 1}];
}
[delegate reader:self didReadLine: line];
}
}
在讀取6MB文件,兩次我會得到一系列96「壞寫着」當CHUNK_SIZE是1024。如果CHUNK_SIZE是512將會有一系列192「不好讀」。 「壞讀」是什麼意思? NSInputStream讀取消息返回成功,並且委託回調中沒有發生錯誤事件。然而,bytes
緩衝區具有全部空值。
- 的iOS 7.0.4,iPad 2的
- 不上桌面
- 發生在模擬器
- 不會發生減少文件大小aprox的。 1MB「修復」在iPad上的問題
最有可能值得注意的是,我在主UI線程上實例化reader類。
所以......我在這裏微妙地(或不是微妙地)做錯了什麼?還是我發現了一些不明顯的iOS錯誤?
我想添加一些NSLog語句,並通過它們試圖找到我的錯誤。此時存在嚴重問題的文件系統的可能性非常小。 –