2009-09-12 12 views
8

Czytam bardzo duży plik przy użyciu NSInputStream i wysyłając je do urządzenia w pakietach. Jeśli odbiornik nie otrzyma pakietu, mogę odesłać go do nadawcy z numerem pakietu, reprezentującym lokalizację początkową w bajtach brakującego pakietu.Czytaj tylko część pliku z dysku w celu-c

Wiem, że NSInputStream nie może cofnąć i pobrać pakietu, ale czy istnieje inny sposób na pobranie żądanego zakresu bajtów bez załadowania całego dużego pliku do pamięci?

Jeśli była metoda [NSData dataWithContentsOfFileAtPath: inRange], byłaby idealna.

+0

Czy oznacza NSInputStream? – Tim

+0

Tak. Miałem na myśli NSInputStream. Przepraszamy za zamieszanie. – coneybeare

+0

Czy masz kontrolę nad tym, co robi urządzenie? Czy możliwe jest wysłanie potwierdzenia odbioru otrzymanych pakietów, więc przechowujesz pakiety w pamięci i wysyłasz je ponownie, aż otrzymasz potwierdzenie? –

Odpowiedz

5

można przewinąć z NSInputStream:

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

nie działa w moim przypadku –

12

Nie sądzę, nie ma standardową funkcją, która to robi, ale można napisać samemu, używając kategorii i 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 

Następnie można w ten sposób:

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

Czy powinienem zwolnić obiekt NSData w funkcji wywołującej? –