2009-09-12 15 views
8

Estoy leyendo un archivo muy grande usando un NSInputStream y enviándolo a un dispositivo en paquetes. Si el receptor no recibe un paquete, puedo devolverlo al remitente con un número de paquete, que representa la ubicación de inicio en bytes del paquete faltante.Leer solo una parte de un archivo del disco en Object-C

Sé que un NSInputStream no puede rebobinar y tomar el paquete, pero ¿hay alguna otra manera de obtener el rango de bytes solicitado sin cargar todo el archivo grande en la memoria?

Si hubiera un método [NSData dataWithContentsOfFileAtPath: inRange], sería perfecto.

+0

¿se refiere a NSInputStream? – Tim

+0

Sí. Quise decir un NSInputStream. Perdón por la confusión – coneybeare

+0

¿Tiene algún control sobre lo que hace el dispositivo? ¿Es posible que envíe una copia de seguridad para los paquetes recibidos, de modo que guarde los paquetes en la memoria y los vuelva a enviar hasta que reciba una confirmación? –

Respuesta

5

Es posible rebobinar con NSInputStream:

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

no funciona en mi caso –

12

No creo que hay una función estándar que hace eso, pero usted podría escribir uno usted mismo, usando una categoría y la 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 

A continuación, puede esto:

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

¿Debo liberar el objeto NSData en la función de llamada? –

Cuestiones relacionadas