Similar to Can I find a filename from a filehandle in Perl? but in Tcl.
I plan to cache filename-filehandle associations anyway, so I'm asking purely out of curiosity--particularly of the "operating system wizardry" mentioned in the link. Is it possible in Tcl?
If it matters, I'm (forced into) using Tcl 8.0.5 on SunOS 5.10.
-path pathPrefix Search for files with the given pathPrefix where the rest of the name matches the given patterns. This allows searching for files with names similar to a given file (as opposed to a directory) even when the names contain glob-sensitive characters.
-- reading a file. The Tcl file commands are file, open, close, gets and read, and puts, seek, tell, and eof, fblocked, fconfigure, Tcl_StandardChannels(3), flush, fileevent, filename. One way to get file data in Tcl is to 'slurp' up the file into a text variable.
Opening Files This is the default mode used when no accessMode is specified. Opens a text file for writing, if it does not exist, then a new file is created else existing file is truncated.
With a version of Tcl that old, you really don't have all that many options. The simplest is to do a little bit of wrapping of open
and 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
}
Then, you can get the filename for an open channel $ch
by just reading $fileForChannel($ch)
.
I looked and did not find any way to get file name from handle, so I created my own solution. This solution uses the trace command to catch when the open command exits. At which time, both file names and handles are available, so I associate them to each other via the global fileNameFromHandle array.
# 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
I don't have Tcl 8.0.5, to verify if this solution works. Please try it out and let me know. You can also trace the close command to remove the association.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With