można użyć NSData +dataWithContentsOfFile:options:error:
zt on NSDataReadingMappedIfSafe
opcja mapowania pliku do pamięci zamiast ładowania go. Dzięki temu będzie korzystać z menedżera pamięci wirtualnej w systemie iOS, aby zapewnić, że bity pliku są wymieniane i usuwane z pamięci RAM w taki sam sposób, jak system operacyjny komputera obsługuje wirtualny plik pamięci na dysku. Tak więc nie potrzebujesz wystarczającej ilości pamięci RAM, aby zachować cały plik w pamięci naraz, wystarczy, że plik będzie wystarczająco mały, aby zmieścił się w przestrzeni adresowej procesora (czyli gigabajtach). Otrzymasz obiekt, który działa dokładnie tak, jak normalny NSData
, co powinno zaoszczędzić Ci większości kłopotów związanych z korzystaniem z NSFileHandle
i ręcznego przesyłania strumieniowego.
Pewnie wtedy trzeba konwertować porcje NSString
ponieważ można realnie oczekiwać, że do konwersji z UTF-8 do innego formatu (choć to może nie, to warto mieć go z -initWithData:encoding:
i sprawdzając czy NSString jest wystarczająco inteligentny tylko po to, aby zachować odniesienie do oryginalnych danych i rozwijać się z UTF-8 na żądanie), o którym myślę, że tak naprawdę jest twoje pytanie.
Proponuję użyć -initWithBytes:length:encoding:
do konwersji rozsądnej liczby bajtów na ciąg znaków. Następnie można użyć numeru -lengthOfBytesUsingEncoding:
, aby dowiedzieć się, ile bajtów faktycznie ma sens i odpowiednio przesuwać wskaźnik odczytu. Jest to bezpieczne założenie, że NSString
odrzuci wszystkie znaki części na końcu dostarczonych bajtów.
EDIT: tak, coś jak:
// map the file, rather than loading it
NSData *data = [NSData dataWithContentsOfFile:...whatever...
options:NSDataReadingMappedIfSafe
error:&youdDoSomethingSafeHere];
// we'll maintain a read pointer to our current location in the data
NSUinteger readPointer = 0;
// continue while data remains
while(readPointer < [data length])
{
// work out how many bytes are remaining
NSUInteger distanceToEndOfData = [data length] - readPointer;
// grab at most 16kb of them, being careful not to read too many
NSString *newPortion =
[[NSString alloc] initWithBytes:(uint8_t *)[data bytes] + readPointer
length:distanceToEndOfData > 16384 ? 16384 : distanceToEndOfData
encoding:NSUTF8StringEncoding];
// do whatever we want with the string
[self doSomethingWithFragment:newPortion];
// advance our read pointer by the number of bytes actually read, and
// clean up
readPointer += [newPortion lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
[newPortion release];
}
oczywiście, ukryte założenie, że wszystkie UTF-8 kodowania są wyjątkowe, które mam nie przyznają się do bycia na tyle kompetentny, aby powiedzieć za absolutną pewność.
Jak duży jest ten plik? Megabajty? Gigabajty? –
Powiedzmy, że rozmiar pliku to 5 MB, ale nie widzę, żeby to miało naprawdę znaczenie. –