与Perl中的Can I find a filename from a filehandle in Perl?类似,这里是关于Tcl的。我计划无论如何都会缓存文件名-文件句柄的关联信息,所以我只是出于好奇而问——特别是在链接中提到的“操作系统魔法”。在Tcl中是否可能实现呢?如果有影响的话,我正在SunOS 5.10上使用Tcl 8.0.5。
使用这么老的Tcl版本,你真的没有太多选择。最简单的方法是对open
和close
进行一些包装:
rename open _original_open
rename close _original_close
proc open {filename args} {
global fileForChannel
set channel [eval [list _original_open $filename] $args]
set fileForChannel($channel) $filename
return $channel
}
proc close {channel} {
global fileForChannel
catch {unset fileForChannel($channel)}
_original_close $channel
}
接着,你可以通过读取$fileForChannel($ch)
来获取打开通道$ch
的文件名。
close
包装为通道名称,因为通常从一小组中选择通道名称。如果您在Windows上,则清理很重要,因为那里的通道名称更加多样化。(这是由于两个平台上文件描述符的不同性质所致。) - Donal Fellowsclose
。谢谢。 - Andrew Cheong我查找了一下,没有找到从句柄获取文件名的方法,所以我自己创建了一个解决方案。这个解决方案使用trace命令来捕获open命令退出时的情况。在此时,文件名和句柄都是可用的,因此我通过全局fileNameFromHandle数组将它们相互关联。
# This script demonstrate the use of the trace command to keep track
# the relationship between file handles and file names
# ======================================================================
# Setup trace to track file handle vs. file name
array set fileNameFromHandle {}
proc trace_proc {command code result op} {
if {$code != 0} return; # Ignore failed calls
set filename [lindex $command 1]; # command = {open filename mode}
set filehandle $result
set ::fileNameFromHandle($filehandle) $filename
}
proc getFileName {handle} { return $::fileNameFromHandle($handle) }
trace add execution open leave trace_proc
# ======================================================================
# Main
set handle1 [open file1.txt r]
# Do something with the files
# Need filename from handle?
puts "Handle: $handle1, filename: [getFileName $handle1]"
close $handle1
我没有Tcl 8.0.5版本,无法验证这个解决方案是否有效。请尝试并告诉我结果。您也可以跟踪close命令以删除关联。