2009-09-12 10 views
8

Sto leggendo un file molto grande utilizzando un NSInputStream e inviandoli a un dispositivo in pacchetti. Se il ricevitore non riceve un pacchetto, posso inviarlo al mittente con un numero di pacchetto, che rappresenta la posizione iniziale in byte del pacchetto mancante.Leggere solo una parte di un file dal disco nell'obiettivo-c

So che NSInputStream non può riavvolgere e prendere il pacchetto, ma esiste un altro modo per afferrare l'intervallo di byte richiesto senza caricare l'intero file di grandi dimensioni in memoria?

Se esistesse un metodo [NSData dataWithContentsOfFileAtPath: inRange], sarebbe perfetto.

+0

Vuoi dire NSInputStream? – Tim

+0

Sì. Intendevo un NSInputStream. Scusa per la confusione – coneybeare

+0

Hai qualche controllo su cosa fa il dispositivo? Potrebbe eventualmente inviare un ack per i pacchetti ricevuti, in modo da tenere i pacchetti in memoria e rinviarli finché non si riceve un ack? –

risposta

5

È possibile riavvolgere con NSInputStream:

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

non funziona nel mio caso –

12

Io non credo che ci sia una funzione standard che lo fa, ma si potrebbe scrivere uno voi stessi, utilizzando una categoria e l'API C stdio:

@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 

Quindi è possibile questo:

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

Dovrei rilasciare l'oggetto NSData nella funzione chiamante? –

Problemi correlati