2011-10-20 5 views
1

Je voudrais lire un fichier d'environ 5 Mo en mémoire ... le fichier a ce format (il est un fichier texte)Lire gros fichier txt en C++

ID 3: 0 itemId.1 0 itemId.2 0 itemId.5 1 itemId.7 ........................ 20 itemId.500 
ID 50: 0 itemId.31 0 itemId.2 0 itemId.4 2 itemId.70 ........................ 20 itemId.2120 
..... 

comment puis-je faire efficacement en C++?

+3

La manière standard n'est-elle pas assez efficace? –

+2

Vous devriez vraiment reconsidérer ce que vous considérez comme "grand". L'estimation est une compétence d'ingénierie. – pmr

+1

Généralement, 5 Mo n'est pas considéré comme grand selon la plate-forme. La plupart des PC peuvent lire un fichier de 5 Mo entièrement en mémoire. –

Répondre

5

lecture d'un fichier ligne par ligne:

ifstream fin ("file.txt"); 
string  myStr; 

while(getline(fin, myStr)) // Always put the read in the while condition. 
{       // Then you only enter the loop if there is data to 
    //use myStr data   // processes. Otherwise you need to read and then 
}       // test if the read was OK 
          // 
          // Note: The last line read will read up to (but not 
          //  past) then end of file. Thus When there is 
          //  no data left in the file its state is still 
          //  OK. It is not until you try and explicitly 
          //  read past the end of file that EOF flag is set. 

Pour une raison de ne pas appeler explicitement voir de près:
https://codereview.stackexchange.com/questions/540/my-c-code-involving-an-fstream-failed-review/544#544

Si l'efficacité est votre objectif majeur (son probablement pas). Ensuite, lisez le fichier entier en mémoire et analysez à partir de là: voir Thomas ci-dessous: Read large txt file in c++

+0

thx pour les leçons (et pour ne pas downvoting moi): p +1 –

+0

Recommanderiez-vous encore cette méthode si l'on voulait utiliser un délimiteur dans les lignes? –

+0

@Shredder: Vous pouvez utiliser 'getline (fin, myStr, '#')' pour un délimiteur de hachage etc. mais sinon le code est le même. –

3

Utilisez un file stream:

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 

int main() { 
    string line; 
    ifstream myfile ("example.txt"); 
    if (myfile.is_open()) 
    { 
     while (getline(myfile, line)) 
      cout << line << endl; 

     myfile.close(); 
    } 
    else 
    { 
     cout << "Unable to open file"; 
    } 

    return 0; 
} 

5MB est vraiment pas un gros fichier. Le flux prendra soin de lire des morceaux à la fois pour vous, mais vraiment; Presque n'importe quelle machine fonctionnera probablement sur 5Mo dans la mémoire sans problème.

+0

Ceci a du code redondant, et essayera de lire une ligne de code de trop. Utilisez les idiomes établis pour lire le texte à la place ('while (getline (myfile, line))', dans ce cas). –

+0

@Konrad: Oui, j'étais fainéant et je l'ai juste copié. Je suppose que je devrais le réparer ... merci. –

4

Lire le fichier entier en mémoire, puis traiter le contenu en mémoire.

Une ressource de fichier (par exemple un disque dur) est plus efficace lorsque le moteur est maintenu en rotation. Une grande lecture de données est donc plus efficace que 5 lectures de petites quantités de données.

Sur la plupart des plateformes, la mémoire est plus rapide d'accès qu'un fichier. En utilisant cette information, on peut rendre un programme plus efficace en lisant des données dans la mémoire puis en traitant la mémoire. La combinaison des deux techniques donnera une plus grande performance: lire autant de données, en une transaction, dans la mémoire, puis traiter la mémoire.

Certaines personnes déclarent des tableaux volumineux de char ou unsigned char (pour les données binaires). D'autres personnes disent à std :: string ou std :: vector de réserver une grande quantité de mémoire, puis de lire les données dans la structure de données. De plus, les lectures de blocs (par exemple, istream::read()) contournent la plupart des parties lentes des installations de flux C++.

+0

bonne info, merci ^^ –