问题描述
谁能告诉我如何更新以下程序来处理大文件(大小
proc read_text_file { file } {
set fp [open ${file} r]
set return_data ""
while { [gets $fp each_line] != -1 } {
lappend return_data ${each_line}
}
close $fp
return ${return_data}
}
谢谢
解决方法
当您有一个非常大的文件时,您绝对希望避免一次将其全部放入内存中。 (此外,Tcl 8.* 具有内存块分配限制,这使得引入 50GB 的数据强烈令人兴奋。这是一个长期存在的 API 错误,已在 9.0 中修复 - 在 alpha 中 - 但您将拥有暂时忍受它。)
如果可以,请遍历文件以确定其有趣的子块在哪里。为了论证起见,让我们假设那些是匹配模式的行;下面是一个示例,用于查找过程在 Tcl 脚本中的位置(在一些简单的假设下)。
proc buildIndices {filename} {
set f [open $filename]
set indices {}
try {
while {![eof $f]} {
set idx [tell $f]
set line [gets $f]
if {[regexp {^proc (\w+)} $line -> name]} {
dict set indices $name $idx
}
}
return $indices
} finally {
close $f
}
}
现在你有了索引,然后你可以从文件中提取一个过程,如下所示:
proc obtainProcedure {filename procName indices} {
set f [open $filename]
try {
seek $f [dict get $indices $procName]
set procedureDefinition ""
while {[gets $f line] >= 0} {
append procedureDefinition $line "\n"
if {[info complete $procedureDefinition]} {
# We're done; evaluate the script in the caller's context
tailcall eval $procedureDefinition
}
}
} finally {
close $f
}
}
你会像这样使用它:
# Once (possibly even save this to its own file)
set indices [buildIndices somefile.tcl]
# Then,to use
obtainProcedure somefile.tcl foobar $indices
如果您经常这样做,请将您的代码转换为使用数据库;从长远来看,它们的效率要高得多。建立索引相当于建立数据库,其他过程相当于做一个数据库查询。