J'ai essayé de chercher cela, mais je ne pouvais pas trouver grand chose. Cela semble être quelque chose qui a probablement été demandé auparavant (plusieurs fois?), Alors je m'excuse si c'est le cas.
Je me demandais ce que le moyen le plus rapide d'analyser certaines parties d'un fichier de rubis serait. Par exemple, supposons que je connaisse em> les informations que je souhaite pour une fonction particulière se situe entre les lignes 500 et 600 de, par exemple, un fichier de 1000 lignes. (Évidemment, ce type de question est orienté vers de nombreux fichiers importants, je suis simplement en train d'utiliser ces plus petits chiffres pour l'exemple), car je sais que ce ne sera pas au premier semestre, est-il un moyen rapide de ne pas tenir compte de cette information ? p> J'utilise actuellement quelque chose sur les lignes de: p> Ça marche, mais je ne peux tout simplement pas m'empêcher de mieux fonctionner . P> Je suis très nouveau à Ruby et je suis intéressé à apprendre de nouvelles façons de faire les choses dedans. p> p>
4 Réponses :
sonne comme lignes () code>. P>
Cela itère juste sur les lignes. Ce n'est pas très utile dans cette situation.
@coreyward: pourquoi pas? Vous pouvez transmettre une gamme et itérair ces lignes. Y a-t-il quelque chose qui me manque?
La bibliothèque IO intégrée fait la même chose.
@coreyward: Je ne comprends toujours pas, désolé. L'OP demande à d'autres moyens de ne lire que certaines lignes de fichiers d'un fichier. Ma réponse échoue-t-elle à cela? Vous avez suggéré quelque chose comme rechercher code>, ce qui ne fonctionnera pas si vous ne pouvez pas savoir combien d'octets vous devriez sauter (par exemple, vous ne savez pas combien de temps chaque enregistrement).
Vous pouvez utiliser io # # Readlines , qui renvoie un tableau avec toutes les lignes
f = File.new(file_in) f.readlines[500..600].each do |line| #line is each line in the file (including the last \n) #stuff end
Ce n'est pas très favorable aux grands fichiers. Construire un tableau avec 500 000 entrées Tout simplement pour accéder de 230 000 à 230 100,100 n'est pas intelligent. Si quelque chose, itérant sur chaque ligne dans le flux et les jeter au besoin, c'est plus intelligent car le fichier ne se chargait pas en mémoire tout à la fois.
Cela pourrait être ma mise en œuvre (et bien sûr, je vais continuer à tester quand j'ai du temps), mais cette méthode semble être un peu plus lente, même sur de petits fichiers d'environ 2000 lignes. Cela dit, la différence est assez petite à ces niveaux (quand j'ai fait f = fichiers.Nouveau ... Readlines [x....y] ... il a fallu ~ 0,85 secondes moyenne; la méthode initiale que j'ai postée me donne environ 0.75Seconde moyenne) bien sûr, je ne le ferais peut-être pas correctement ou très bien. Je vais faire d'autres tests.
Je ne sais pas s'il y a un moyen équivalent de faire cela pour les lignes, mais vous pouvez utiliser voir io # recherche ou voir rechercher code> ou le décalage code> de décalage code> sur un objet IO sur "Skip "octets. p>
Pour savoir où une ligne se termine (avec un caractère EOL), il n'y a aucun moyen de sortir, vous devez lire le fichier octet-byte, puis déposer les informations de lecture. Si vous recherchez au 1000e octet, vous n'avez aucun moyen de dire combien de lignes vous avez sauté. Il peut être 400 ou 1 ou même zéro.
file.lines.tap{|enum| 500.times{enum.next}}.take(100)
Cela a l'air plus rubish! J'avais vraiment pensé à cela après avoir posté la question - le fait que les "lignes" ne soient pas vraiment définies par rien d'autre que "l'espace entre" nouvelles lignes "caractères" (ou plutôt avant et après). Ce qui signifierait qu'ils doivent tous être analysés pour ce personnage de toute façon. Je suppose que si j'avais une idée générale de l'espace précédant les lignes requises, dans les bits / octets / peu importe, je pouvais sauter cette zone, puis commencer à analyser la ligne par ligne, mais pour le moment, je vais accepter que cela fonctionne assez bien comme est. Ou comme si je serai avec une ligne plus agréable comme la vôtre! Merci.
En fait, vous pourrait i> utiliser rechercher code> si les lignes contenaient des informations relatives à leur position dans le fichier (telles que les numéros de ligne ou les horodatages triés). Ensuite, vous pourriez tirer une variante de la recherche binaire. Vous pouvez ouvrir une autre question si cela aiderait dans votre cas particulier.
Cela conduit cependant à des problèmes d'évolutivité. Si le fichier comporte plusieurs millions de lignes, il va être lu complètement dans la mémoire avant de pouvoir goutte code>. Cela pourrait être lent et rendre la machine ne répond pas comme sa chargement des données ou remplissez toute la mémoire disponible si les lignes sont longues, provoquant une pagination. Pour une approche plus sûre avec un fichier texte, vous ferez mieux de les lire une ligne à la fois, sautez-les jusqu'à ce que vous atteigniez ceux que vous souhaitez, capturez uniquement les lignes nécessaires.
@L'imin man: Qu'est-ce qui vous fait penser qu'il a besoin de charger un fichier entier afin de goutte code>?
goutte code> est dans
tableau code>, ce qui impliquait qu'il a dû avoir un
silencieux sur code> d'abord. Je viens d'envisager et que le tableau obtient de
énumérable code> et le code source indique qu'il boucle sur son bloc
(n) code> épuiser le résultat. Donc, il n'a pas à tout charger en mémoire; Il faut charger les lignes de manière séquentielle et les jeter. Et, comme vous le dites, il existe différentes façons de l'écrire, mais le résultat final est identique, les lignes sont en lecture juste pour être comptées. Et, c'était mon point, que les lignes de lecture skient individuellement un problème d'évolutivité, vs.
slurping code> un fichier qui peut tuer un hôte.
Pour Ruby 2.0.0P247, vous devez utiliser chaque_line: AVERTISSEMENT: IO # Les lignes sont obsolètes; utiliser #each_line à la place