2009-06-01 1 views

risposta

0

Aprire il file:

NSData *fileData = [NSData dataWithContentsOfFile:fileName]; 

Leggere i byte che si desidera:

int bytes[1000]; 
[fileData getBytes:bytes length:sizeof(int) * 1000]; 
+0

Non conosco il cacao, ma: perché stai usando 'int' piuttosto che' char'? – poundifdef

+5

In questo esempio, l'intero file deve essere letto prima di leggere quei N byte. Nel mio caso quando il file è di circa 900 MB questo metodo sembra essere un po '"hardcore" –

+0

Un int è almeno due byte (di solito 4), e in origine l'ho scritto per usare char, che è generalmente un byte. Di solito penso che sia meglio non pensare che ogni tipo abbia un numero specifico di byte. Probabilmente è attribuibile ai miei giorni UNIX :-) – Alex

2

Se si vuole evitare di leggere l'intero file, è possibile utilizzare solo le funzioni standard CI/O:

#include <stdio.h> 
... 
FILE *file = fopen("the-file.dat", "rb"); 
if(file == NULL) 
    ; // handle error 
char theBuffer[1000]; // make sure this is big enough!! 
size_t bytesRead = fread(theBuffer, 1, 1000, file); 
if(bytesRead < 1000) 
    ; // handle error 
fclose(file); 
+0

Mi chiedo se questo risolverà correttamente gli alias di Finder nel percorso fornito? – neoneye

+0

Dovrebbe; Credo che gli alias del Finder siano solo collegamenti simbolici e che stdio possa gestire correttamente i collegamenti simbolici. Per capire l'obiettivo di un link simbolico di leggere il file di destinazione, si può usare la funzione readlink (2), vedere http://linux.die.net/man/2/readlink. –

+0

Gli alias del Finder non sono collegamenti simbolici. Il Finder supporta entrambi, ma crea alias. –

23

-[NSFileHandle readDataOfLength:].

NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:filePath]; 
NSData *fileData = [handle readDataOfLength:N]; 
[handle closeFile]; 
+0

Puoi fare un esempio per favore? –

+4

[[NSFileHandle fileHandleForReadingAtPath: path] readDataOfLength: length] –

+0

Se stai seguendo il commento sopra, assicurati di chiamare -closeFile sul manico dopo. – Dov

24

Se si vuole l'accesso casuale ai contenuti del file in un modo simile a aver caricato via NSData ma senza in realtà leggendo tutto in memoria, è possibile utilizzare la mappatura della memoria. Ciò significa che il file su disco viene trattato come una sezione di memoria virtuale e verrà inserito e disinserito come una normale memoria virtuale.

NSError * error = nil; 
NSData * theData = [NSData dataWithContentsOfFile: thePath 
              options: NSMappedRead 
              error: &error]; 

Se non si cura di ottenere dettagli sugli errori del file system, si può semplicemente utilizzare:

NSData * theData = [NSData dataWithContentsOfMappedFile: thePath]; 

allora si sarebbe semplicemente utilizzare il metodo di NSData -getBytes:range: di tirare fuori pezzi di dati specifici, e solo il parti rilevanti del file verranno effettivamente lette dalla memoria permanente; anche loro potranno essere espulsi.

+1

Questa è una bella idea, non ci avrei pensato. Ricorda che quando si mappano i file in memoria, è probabilmente ancora più importante assicurarsi di rilasciare correttamente l'oggetto, poiché le perdite hanno un effetto più ampio. –

+2

sai se questo è diverso da NSInputStream * stream = [NSInputStream inputStreamWithFileAtPath: thePath]; [stream read: theBuffer maxLength: 255]; ? presumo che siano identici – valexa

+1

NSInputStream leggerà i blocchi dal filesystem in modo discreto. Se accedi al file in modo sequenziale, lo streaming è buono.Se hai bisogno di accesso casuale, allora NSFileHandle o un oggetto dati mappato sono la strada da percorrere, quest'ultima essendo più ottimizzata per l'accesso casuale complessivo. –