Objective-C: leer un archivo línea por línea

Resuelto asked hace 15 años • 18 respuestas

¿Cuál es la forma adecuada de tratar con archivos de texto grandes en Objective-C? Digamos que necesito leer cada línea por separado y quiero tratar cada línea como un NSString. ¿Cuál es la forma más eficiente de hacer esto?

Una solución es utilizar el método NSString:

+ (id)stringWithContentsOfFile:(NSString *)path 
      encoding:(NSStringEncoding)enc 
      error:(NSError **)error 

y luego dividir las líneas con un separador de nueva línea y luego iterar sobre los elementos de la matriz. Sin embargo, esto parece bastante ineficiente. ¿No existe una manera fácil de tratar el archivo como una secuencia, enumerando cada línea, en lugar de simplemente leerlo todo de una vez? Algo así como java.io.BufferedReader de Java.

 avatar Jun 25 '09 21:06
Aceptado

Esto funcionará para lecturas generales Stringde Text. Si desea leer texto más largo (texto de gran tamaño) , utilice el método que mencionaron otras personas aquí, como el almacenamiento en búfer (reservar el tamaño del texto en el espacio de memoria) .

Digamos que lees un archivo de texto.

NSString* filePath = @""//file path...
NSString* fileRoot = [[NSBundle mainBundle] 
               pathForResource:filePath ofType:@"txt"];

Quiere deshacerse de la nueva línea.

// read everything from text
NSString* fileContents = 
      [NSString stringWithContentsOfFile:fileRoot 
       encoding:NSUTF8StringEncoding error:nil];

// first, separate by new line
NSArray* allLinedStrings = 
      [fileContents componentsSeparatedByCharactersInSet:
      [NSCharacterSet newlineCharacterSet]];

// then break down even further 
NSString* strsInOneLine = 
      [allLinedStrings objectAtIndex:0];

// choose whatever input identity you have decided. in this case ;
NSArray* singleStrs = 
      [currentPointString componentsSeparatedByCharactersInSet:
      [NSCharacterSet characterSetWithCharactersInString:@";"]];

Ahí tienes.

Yoon Lee avatar Dec 17 '2010 01:12 Yoon Lee

Esa es una gran pregunta. Creo que @Diederik tiene una buena respuesta, aunque es lamentable que Cocoa no tenga un mecanismo para exactamente lo que quieres hacer.

NSInputStreamle permite leer fragmentos de N bytes (muy similar a java.io.BufferedReader), pero debe convertirlos por NSStringsu cuenta, luego buscar nuevas líneas (o cualquier otro delimitador) y guardar los caracteres restantes para la siguiente lectura, o leer más caracteres si aún no se ha leído una nueva línea. ( NSFileHandlele permite leer un NSDataque luego puede convertir en un NSString, pero es esencialmente el mismo proceso).

Apple tiene una Guía de programación de transmisiones que puede ayudar a completar los detalles, y esta pregunta SO también puede ser útil si va a tratar con uint8_t*buffers.

Si va a leer cadenas como esta con frecuencia (especialmente en diferentes partes de su programa), sería una buena idea encapsular este comportamiento en una clase que pueda manejar los detalles por usted, o incluso crear subclases NSInputStream(está diseñada para ser subclassed ) y agregando métodos que le permitan leer exactamente lo que desea.

Para que conste, creo que sería una buena característica agregar y presentaré una solicitud de mejora para algo que lo haga posible. :-)


Editar: Resulta que esta solicitud ya existe. Hay un radar que data de 2006 para esto (rdar://4742914 para personas internas de Apple).

Quinn Taylor avatar Jun 25 '2009 18:06 Quinn Taylor