2009-09-12 9 views
8

Ich lese eine sehr große Datei mit einem NSInputStream und sende sie an ein Gerät in Paketen. Wenn der Empfänger kein Paket erhält, kann ich mit einer Paketnummer zum Absender zurücksenden, die den Startort in Bytes des fehlenden Pakets darstellt.Lies nur einen Teil einer Datei von der Festplatte in objective-c

Ich weiß, ein NSInputStream kann das Paket nicht zurückspulen und greifen, aber gibt es eine andere Möglichkeit, den angeforderten Bytebereich zu erfassen, ohne die gesamte große Datei in den Speicher zu laden?

Wenn es eine Methode [NSData dataWithContentsOfFileAtPath: inRange] gäbe, wäre sie perfekt.

+0

Haben Sie NSInputStream bedeuten? – Tim

+0

Ja. Ich meinte einen NSInputStream. Entschuldigung für die Verwirrung – coneybeare

+0

Haben Sie eine Kontrolle darüber, was das Gerät macht? Könnte es möglicherweise eine Bestätigung für empfangene Pakete senden, so dass Sie Pakete im Speicher behalten und sie erneut senden, bis Sie eine Bestätigung erhalten? –

Antwort

5

Sie können mit NSInputStream zurückspulen:

[stream setProperty:[NSNumber numberWithInt:offset] 
      forKey:NSStreamFileCurrentOffsetKey]; 
+0

funktioniert in meinem Fall nicht –

12

Ich glaube nicht, dass es eine Standardfunktion ist, die das tut, aber man konnte man selbst schreiben, eine Kategorie und die C stdio API:

@interface NSData(DataWithContentsOfFileAtOffsetWithSize) 
+ (NSData *) dataWithContentsOfFile:(NSString *)path atOffset:(off_t)offset withSize:(size_t)bytes; 
@end 

@implementation NSData(DataWithContentsOfFileAtOffsetWithSize) 

+ (NSData *) dataWithContentsOfFile:(NSString *)path atOffset:(off_t)offset withSize:(size_t)bytes 
{ 
    FILE *file = fopen([path UTF8String], "rb"); 
    if(file == NULL) 
     return nil; 

    void *data = malloc(bytes); // check for NULL! 
    fseeko(file, offset, SEEK_SET); 
    fread(data, 1, bytes, file); // check return value, in case read was short! 
    fclose(file); 

    // NSData takes ownership and will call free(data) when it's released 
    return [NSData dataWithBytesNoCopy:data length:bytes]; 
} 

@end 

dann können Sie dies:

// Read 100 bytes of data beginning at offset 500 from "somefile" 
NSData *data = [NSData dataWithContentsOfFile:@"somefile" atOffset:500 withSize:100]; 
+0

Sollte ich NSData Objekt in Anruferfunktion freigeben? –