0
votes

Comment puis-je lire la nième ligne d'un fichier efficacement dans Ruby?

J'ai un fichier de 2 gib, et je veux lire la première ligne du fichier. Je peux appeler la méthode Readlines de fichier qui renvoie une matrice et utilisez [0] Syntaxe du support, AT (0) ou le Tranche (0) ou d'abord méthodes.

Mais il y a un problème. Mon PC dispose de 3,7 GIB RAM, et l'utilisation passe de 1,1 gib jusqu'à 3,7 gib. Mais tout ce que je veux, c'est la première ligne du fichier. Y a-t-il un moyen efficace de le faire?


3 commentaires

Est-ce que cela répond à votre question? Comment obtenir une ligne particulière d'un fichier


Euh non, imaginez une situation exagérée d'avoir une centaine de fichiers GB. Lorsque vous exécutez queue 100_gb_file , la queue ne lira que les 10 dernières lignes ou les lignes données. Vous n'avez essentiellement besoin d'exécuter des milliards d'itérations et d'appeler .NEXT () sur io.foreach (fichier, séparateur) ou vous ne pouvez pas lire tout le fichier Puny 8 Go de RAM. Je ne sais pas si cela est possible à Ruby. Mais j'ai résolu ce problème avec Ruby C Extension, en particulier la lecture du fichier en C. Cela résolvait vraiment mon problème: geeksforgeeks.org/... . Mais ce n'est pas une vraie solution rubis ...


Bon à savoir sur votre solution, mais votre question ne concerne pas la queue.


4 Réponses :


0
votes

Avez-vous essayé readline code> au lieu de Readlines code>?

File.open('file-name') { |f| f.readline }


2 commentaires

Oui, il consomme une bonne quantité de mémoire! Seuls ReadPartial ne mange pas beaucoup de choses ...


Parce que le fichier contient du texte ASCII, je peux le faire: ch = '' .TAP {| a | Fichier.open ('hello.txt') {| x | Boucle jusqu'à A.ConCat (X.ReadPartial (1)) [- 1] ==? \ n}} Pour l'instant, sans causer de problèmes de mémoire ... Cela lira la première ligne. Mais si la première ligne contient un caractère de nouvelle ligne, il faudra cette ligne vide. bande peut être utilisé pour désactiver les espaces supplémentaires ou les nouvelles lignes. La réponse provoque toujours un problème de mémoire, mais merci d'avoir tenté de répondre.



0
votes

Qu'en est-il de io.foreach ? XXX

Cela devrait lire la première ligne, l'imprimer, puis arrêter. Il ne lit pas le fichier entier; Il lit une ligne à la fois.


1 commentaires

Merci, io.foreach ('hello.txt'). Premier fonctionne parfaitement! Ou io.foreach ('hello.txt'). Prenez (2) .à_a [1] pour obtenir la deuxième ligne ...



1
votes

J'utiliserais des commandes. Par exemple, de cette manière: xxx

J'espère que cela vous a utile.


5 commentaires

Merci de répondre. Mais c'est un choix terrible d'utiliser Shell à l'intérieur de Ruby. J'essaie toujours d'éviter ça. Vous appelez un binaire séparé. En outre, un problème est que ce n'est pas une manière rubis. Votre système avec Ruby aura l'IO et la classe de fichiers. Mais votre système peut être manquant de chat! L'autre chose est que les binaires appelants sont lents. J'ai aspiré la méthode Effacer et Imprimer "\ e [2j \ e [h \ e [3j" . Les deux font le même travail, mais l'ANSI ONE est un 100K fois plus rapide. Je n'utiliserais ces choses que pour Mruby, mais ma question concerne le général Ruby ou IRM. Désolé mais -1 pour ça ...


@ S.Goswami Je supprimerais le bowvote. Utilisez vos bowvotes à chaque fois que vous rencontrez un poste flagreux, sans effort sans effort, ni une réponse clairement et peut-être dangereusement incorrecte. Cette réponse est fonctionnellement correcte, même si ce n'est pas optimal ou parfait pour votre cas d'utilisation et que dans de nombreuses circonstances, fonctionnent exactement comme une personne s'y attendre.


@Anothermh, je vous ai eu, mais votre programme dans ce cas dépend du chat et de la tête. Vous n'avez pas besoin de le faire car Ruby a tout construit pour vous. C'est utile pour ceux qui utilisent MMUBY. Par exemple, io.foreach est disponible sur Linux, Windows et Mac, ainsi que Android, et ce que vous suivez le répondeur, vous êtes laissé avec Linux / Unix ... et aussi exec (...) entraînera la sortie de votre programme une fois les commandes exécutées ... Oui, c'est une autre possibilité d'appeler Shell, mais si vous faites une référence de lecture d'un fichier de gig et de lire la première ligne 100K fois, vous saurez sûrement la différence!


@Anothermh, c'est une réponse correcte, mais ce n'est pas rugueux? Vous pouvez utiliser Perl / Python / Lua, etc. Inside of Kernel # `` `` ` / EXED / Système de noyau / io # popen etc. au lieu du script de bash, qui sera plus lent mais fonctionnera. C'est pourquoi je pense qu'il n'y a pas beaucoup d'efforts accordés pour écrire la réponse. Ça ne pense tout simplement pas à la Ruby Way ...


Nous pouvons choisir de désaccord. Mais je vous rappelle qu'il y a une différence entre inefficace et incorrecte et entre «correct pour certaines plates-formes mais pas d'autres» et incorrecte.



0
votes

Alors je suis venu avec un code qui fait le travail de manière assez efficace.

Tout d'abord, nous pouvons utiliser le io # # chaque_line méthode. Disons que nous avons besoin de la ligne à 3 000 000: xxx

exécuté avec le temps Heure coquille intégré:

[J'ai un grand bonjour fichier .txt avec #! / usr / bin / ruby ​​-w #lineno en elle !!] xxx

Nous pouvons également obtenir la 1ère ligne très facilement! Vous l'avez ...

Deuxièmement, prolongeant la réponse d'un autre membre: xxx

exécuté avec heure : < PRE> XXX

Il pourrait y avoir d'autres façons comme le io # # ReadPartial , io # sysdread et ainsi de suite. Mais le io.foreach , et io # chaque_line est le plus facile et assez rapide de travailler avec.

espère que cela vous aide!


0 commentaires