La lectura de un archivo línea por línea en C ++ se puede hacer de diferentes maneras.
[Rápido] Loop con std :: getline ()
El enfoque más simple es abrir un std :: ifstream y un bucle usando llamadas std :: getline (). El código es limpio y fácil de entender.
#include <fstream>
std::ifstream file(FILENAME);
if (file.is_open()) {
std::string line;
while (std::getline(file, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
file.close();
}
[Rápido] Utilice el archivo_description_source de Boost
Otra posibilidad es usar la biblioteca Boost, pero el código se vuelve un poco más detallado. El rendimiento es bastante similar al código anterior (bucle con std :: getline ()).
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <fcntl.h>
namespace io = boost::iostreams;
void readLineByLineBoost() {
int fdr = open(FILENAME, O_RDONLY);
if (fdr >= 0) {
io::file_descriptor_source fdDevice(fdr, io::file_descriptor_flags::close_handle);
io::stream <io::file_descriptor_source> in(fdDevice);
if (fdDevice.is_open()) {
std::string line;
while (std::getline(in, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
fdDevice.close();
}
}
}
[Más rápido] Usar código C
Si el rendimiento es crítico para su software, puede considerar usar el lenguaje C. Este código puede ser 4-5 veces más rápido que las versiones de C ++ anteriores, consulte el punto de referencia a continuación
FILE* fp = fopen(FILENAME, "r");
if (fp == NULL)
exit(EXIT_FAILURE);
char* line = NULL;
size_t len = 0;
while ((getline(&line, &len, fp)) != -1) {
// using printf() in all tests for consistency
printf("%s", line);
}
fclose(fp);
if (line)
free(line);
Punto de referencia: ¿cuál es más rápido?
He hecho algunos puntos de referencia de rendimiento con el código anterior y los resultados son interesantes. He probado el código con archivos ASCII que contienen 100,000 líneas, 1,000,000 líneas y 10,000,000 líneas de texto. Cada línea de texto contiene 10 palabras en promedio. El programa se compila con -O3
optimización y su salida se reenvía /dev/null
para eliminar la variable de tiempo de registro de la medición. Por último, pero no menos importante, cada fragmento de código registra cada línea con la printf()
función para mantener la coherencia.
Los resultados muestran el tiempo (en ms) que tomó cada fragmento de código para leer los archivos.
La diferencia de rendimiento entre los dos enfoques de C ++ es mínima y no debería hacer ninguna diferencia en la práctica. El rendimiento del código C es lo que hace que el punto de referencia sea impresionante y puede cambiar el juego en términos de velocidad.
10K lines 100K lines 1000K lines
Loop with std::getline() 105ms 894ms 9773ms
Boost code 106ms 968ms 9561ms
C code 23ms 243ms 2397ms

int a, b; char c; while ((infile >> a >> c >> b) && (c == ','))
while(getline(f, line)) { }
construcción y con respecto al manejo de errores, eche un vistazo a este (mi) artículo: gehrcke.de/2011/06/… (Creo que no necesito tener mala conciencia publicando esto aquí, incluso un poco antes fecha esta respuesta).