我对编程很陌生,所以要温柔。我正在尝试从库数据库.dat文件中提取IBSN编号。我编写的代码有效,但它只搜索180MB文件的大约一半。如何调整它来搜索整个文件?或者我如何编写一个程序,将dat文件拆分成可管理的块?
编辑:这是我的代码:
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
答案 0 :(得分:4)
您应该尝试捕获异常以检查问题是否确实存在于读取块上。
就是这样你知道我已经用类似的语法编写了一个脚本来搜索~8GB的真实大文件而没有问题。
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
答案 1 :(得分:3)
最主要的是清理并结合正则表达式以获得性能优势。此外,您应始终对文件使用块语法,以确保正确关闭fd。 File#each不会将整个文件加载到内存中,它一次只执行一行:
File.open("resultsfinal.txt","w+") do |output|
File.open("bibrec2.dat").each do |line|
output.puts line.scan(/a[\dxX]{10}(?:[\dxX]{3}|\W)/)
end
end
答案 2 :(得分:2)
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
答案 3 :(得分:1)
至于性能问题,我看不出任何特别担心文件大小的问题:180MB不应该造成任何问题。运行脚本时内存使用会发生什么变化?
但是,我不确定您的正则表达式是否正在执行您想要的操作。例如:
/[a]{1}[1234567890xX]{10}\W/
(我认为)这个:
有几个样本ISBN匹配器here和here,虽然它们似乎匹配的东西更像我们在书的封底上看到的格式,我猜你的输入文件已经删除了一些格式化。
答案 4 :(得分:1)
您可以查看使用File#truncate
和IO#seek
并使用二进制搜索类型算法。 #truncate
可能具有破坏性,因此您应该复制该文件(我知道这很麻烦)。
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
代码高度未经测试,易碎且不完整。但我希望它能为你提供一个平台。
答案 5 :(得分:-2)
如果您在现代操作系统上进行编程并且计算机有足够的内存(比如512megs),Ruby应该可以将整个文件读入内存。
当您在典型的32位操作系统上获得大约2 GB的工作集时,通常会遇到麻烦。