2009-06-01 21 views

Respuesta

0

Abrir el archivo:

NSData *fileData = [NSData dataWithContentsOfFile:fileName]; 

Leer los bytes que desee:

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

No sé cacao, pero: ¿por qué estás usando 'int' en lugar de' char'? – poundifdef

+5

En este ejemplo, el archivo completo debe leerse antes de leer esos N bytes. En mi caso, cuando el archivo tiene aproximadamente 900 MB, este método parece ser un poco "duro" –

+0

Un int tiene al menos dos bytes (generalmente 4), y originalmente lo escribí para usar char, que generalmente es de un byte. Por lo general, creo que es mejor no suponer que cualquier tipo tenga un número específico de bytes. Eso es probablemente atribuible a mis días en UNIX :-) – Alex

2

Si se quiere evitar leer el archivo completo, sólo puede utilizar las funciones de E/S estándar CI:

#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

Me pregunto si esto resolverá correctamente los alias del Finder en la ruta dada. – neoneye

+0

Debería; Creo que los alias de Finder son solo enlaces simbólicos, y stdio puede manejar los enlaces simbólicos correctamente. Para descubrir el objetivo de un enlace simbólico en lugar de leer el archivo objetivo, se puede usar la función readlink (2), ver http://linux.die.net/man/2/readlink. –

+0

Los alias de Finder no son enlaces simbólicos. Finder admite ambos, pero crea alias. –

23

-[NSFileHandle readDataOfLength:].

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

¿Puedes dar un ejemplo, por favor? –

+4

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

+0

Si está siguiendo el comentario anterior, asegúrese de llamar a -closeFile en el identificador después. – Dov

24

Si desea tener acceso aleatorio a los contenidos del archivo de una manera similar a la de haber cargado a través de NSData pero sin llegar a leer todo en la memoria, se puede utilizar la asignación de memoria. Si lo hace, significa que el archivo en el disco se trata como una sección de la memoria virtual, y se colocará una paginación dentro y fuera de la memoria virtual regular.

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

Si no se preocupan por conseguir detalles de los errores del sistema de archivos, sólo se puede utilizar:

NSData * theData = [NSData dataWithContentsOfMappedFile: thePath]; 

A continuación, sólo podría utilizar el método de NSData -getBytes:range: de sacar piezas específicas de los datos, y sólo el las partes relevantes del archivo se leerán del almacenamiento permanente; también serán elegibles para ser localizados.

+1

Esa es una idea genial, no hubiera pensado en eso. Recuerde que al mapear archivos en la memoria, es discutible que sea aún más crítico asegurarse de liberar el objeto correctamente, ya que las filtraciones tienen un efecto más amplio. –

+2

¿sabe si esto es diferente de NSInputStream * stream = [NSInputStream inputStreamWithFileAtPath: thePath]; [lectura de la secuencia: theBuffer maxLength: 255]; ? supongo que son idénticos – valexa

+1

NSInputStream leerá fragmentos del sistema de archivos discretamente. Si está accediendo al archivo de forma secuencial, la transmisión es buena.Si necesita acceso aleatorio, entonces NSFileHandle o un objeto de datos mapeado son el camino a seguir, este último está más optimizado para el acceso aleatorio en general. –

Cuestiones relacionadas