J'ai quelques fichiers .gz compressés qui est d'environ 5-7gig non compressé. Ce sont des fichiers plats.comment puis-je lire un énorme fichier .gz (plus de 5 gig non compressé) en c
J'ai écrit un programme qui prend un fichier non compressé, et le lit ligne par ligne, ce qui fonctionne parfaitement.
Maintenant, je veux être en mesure d'ouvrir les fichiers compressés inmemory et exécuter mon petit programme. J'ai regardé dans zlib mais je ne peux pas trouver une bonne solution.
Le chargement du fichier entier est impossible en utilisant gzread (gzFile, void *, unsigned), à cause de la limitation de 32bit unsigned int.
J'ai essayé gzgets, mais ce double presque le temps d'exécution, vs lecture en utilisant gzread. (Je l'ai testé sur un échantillon 2gig.)
J'ai aussi regardé dans « tampon », comme le fractionnement le processus gzread en plusieurs morceaux de 2gig, trouvez le dernier retour de ligne en utilisant strcchr, puis en définissant le gzseek. Mais gzseek va émuler une décompression totale de fichier. ce qui est très lent.
Je ne vois aucune solution saine à ce problème. Je pourrais toujours faire quelques vérifications, si une ligne courante a réellement une nouvelle ligne (devrait seulement se produire dans la dernière ligne partiellement lue), et puis lire plus de données du point dans le programme où ceci se produit. Mais cela pourrait devenir très moche.
Avez-vous des suggestions?
grâce
modifier: Je ne besoin d'avoir le dossier complet à la fois, juste besoin d'une ligne de temps, mais je suis arrivé une machine assez énorme, donc si tel était le plus facile que je n'aurais aucun problème.
Pour tous ceux qui suggèrent de canaliser le stdin, j'ai connu des ralentissements extrêmes par rapport à l'ouverture du fichier. Voici un petit extrait de code que j'ai fait il y a quelques mois, qui l'illustre.
time ./a.out 59846/59846.txt
# 59846/59846.txt
18255221
real 0m4.321s
user 0m2.884s
sys 0m1.424s
time ./a.out <59846/59846.txt
18255221
real 1m56.544s
user 1m55.043s
sys 0m1.512s
Et le code source
#include <iostream>
#include <fstream>
#define LENS 10000
int main(int argc, char **argv){
std::istream *pFile;
if(argc==2)//ifargument supplied
pFile = new std::ifstream(argv[1],std::ios::in);
else //if we want to use stdin
pFile = &std::cin;
char line[LENS];
if(argc==2) //if we are using a filename, print it.
printf("#\t%s\n",argv[1]);
if(!pFile){
printf("Do you have permission to open file?\n");
return 0;
}
int numRow=0;
while(!pFile->eof()) {
numRow++;
pFile->getline(line,LENS);
}
if(argc==2)
delete pFile;
printf("%d\n",numRow);
return 0;
}
Merci pour vos réponses, je suis toujours en attente de la pomme d'or
Edit2: en utilisant les pointeurs de fichier de cstyle au lieu de C++ flux est beaucoup plus plus rapide. Donc je pense que c'est la voie à suivre.
Merci pour tous vos commentaires
Enregistrement d'un fichier de 5 Go en mémoire est une mauvaise idée. Peut-être pourriez-vous expliquer pourquoi vous voulez faire cela, afin que nous puissions vous aider avec une meilleure façon de le faire. –