Je suis assez nouveau à la programmation, alors soyez gentil. J'essaie d'extraire des numéros IBSN à partir d'une base de données de bibliothèque .dat fichier. J'ai écrit le code qui fonctionne, mais il ne fait que rechercher environ la moitié du fichier de 180 Mo. Comment puis-je l'ajuster pour rechercher dans l'ensemble du fichier? Ou comment puis-je écrire un programme, la volonté divisera le fichier dat en morceaux gérables?
Edit: em> Voici mon code: p> export = File.new("resultsfinal.txt","w+")
File.open("bibrec2.dat").each do |line|
line.scan(/[a]{1}[1234567890xX]{10}\W/) do |x|
export.puts x
end
line.scan(/[a]{1}[1234567890xX]{13}/) do |x|
export.puts x
end
end
6 Réponses :
Si vous programmez sur un système d'exploitation moderne et que l'ordinateur dispose de suffisamment de mémoire (disons 512Megs), Ruby ne doit pas avoir de problème à lire tout le fichier en mémoire. p>
Les choses obtiennent généralement si vous arrivez à propos d'un groupe de travail de 2 gigaoctets sur un système d'exploitation 32bits typique. P>
Eh bien, le mien obtiendra mal avec 4 Go sur Vista, si cela aide. En outre, cela n'aborge pas une erreur, juste un ensemble de résultats incomplets.
Je crois qu'il signifie que les données sont de 4 Go et non la taille de votre mémoire. Les systèmes d'exploitation 32 bits ne peuvent pas gérer plus d'environ environ 3,5 Go de RAM. Vous n'avez donc pas de 4 Go de RAM de travail à votre disposition, peu importe (sauf si vous utilisez 64 bits Vista). Si votre ensemble de données n'est que 180 Mo, le problème doit être dans votre code. Posteriez-vous le script?
Pas de problème, je vais le poster demain. Merci beaucoup.
Quant au problème de la performance, je ne peux rien voir particulièrement nous inquiéter de la taille du fichier: 180 Mo ne devraient pas poser de problèmes. Qu'advient-il de l'utilisation de la mémoire lorsque vous exécutez votre script?
Je ne suis pas sûr que vos expressions régulières font ce que vous voulez. Ceci, par exemple: p> fait (je pense) ceci: p> Il y a quelques échantillons de matchers ISBN Ici et ici , bien qu'ils semblent correspondre à quelque chose de plus comme Le format que nous voyons sur la couverture arrière d'un livre et que vous devinez que votre fichier d'entrée a dépouillé une partie de ce formatage. p> p>
Ouais, le fichier de données d'origine a reformaté les ISBNS afin qu'ils soient dans ce format. Je ne sais pas pourquoi ça me fait ça! Bon appel à l'écriture juste 'A', semble beaucoup plus simple.
Vous devriez essayer d'attraper une exception pour vérifier si le problème est vraiment sur le bloc de lecture ou non.
Juste pour que vous sachiez que j'ai déjà fait un script avec un peu la même syntaxe pour rechercher un véritable gros fichier de ~ 8 Go sans problème . P>
export = File.new("resultsfinal.txt","w+")
File.open("bibrec2.dat").each do |line|
begin
line.scan(/[a]{1}[1234567890xX]{10}\W/) do |x|
export.puts x
end
line.scan(/[a]{1}[1234567890xX]{13}/) do |x|
export.puts x
end
rescue
puts "Problem while adding the result"
end
end
file = File.new("bibrec2.dat", "r")
while (line = file.gets)
line.scan(/[a]{1}[1234567890xX]{10}\W/) do |x|
export.puts x
end
line.scan(/[a]{1}[1234567890xX]{13}/) do |x|
export.puts x
end
end
file.close
L'essentiel est de nettoyer et de combiner la regex pour les avantages de la performance. Vous devez également utiliser la syntaxe de bloc avec des fichiers pour vous assurer que les FD sont correctement fermés. # # # Chacune ne charge pas le fichier entier en mémoire, il fait une ligne à la fois:
Vous pouvez rechercher à l'aide de Fichier # tronquer code> et io # rechercher code> et utilisez l'algorithme de recherche binaire. #trunate code> peut être destructeur afin que vous puissiez dupliquer em> le fichier (je sais que c'est un problème). middle = File.new("my_huge_file.dat").size / 2
tmpfile = File.new("my_huge_file.dat", "r+").truncate(middle)
# run search algoritm on 'tmpfile'
File.open("my_huge_file.dat") do |huge_file|
huge_file.seek(middle + 1)
# run search algorithm from here
end
Et si vous divisez votre dossier au milieu d'une ligne? ;)
@ ZED_0XFF: L'approche de Yoann Le Touche n'a pas lu un fichier entier en mémoire.