Tcl/Tk--文件操作

wikibook上的文章很有水平,特翻译出来,晒晒。

(译自wikibook,开放书籍库)

文件与通道
    Tcl除了具有C语言里面的stdio库的功能外,还提供很多其他的文件操作命令,很像shell脚本,虽然比较繁琐。见下面的例子:
    glob *.tcl
用来列出当前目录下的所有.tcl文件。
file copy /from/path/file.ext /to/path
.
file delete /from/path/file.ext
.
file rename before.txt after.txt
.
cd /an/other/directory
.
pwd
如果要临时更换目录,执行代码,可以这样:
set here [pwd]
cd $someotherdir
#... code here
cd $here

更准确的来说,一般很多文件操作工作都是用"通道"来实现的,如:
1、标准通道 (stdin, stdout, stderr)
2、打开的普通文件 (open ...)
3、管道命令 (|)
4、套接字 (TCP)

文件名
      通常,文件时用路径名来定位的,在Unix下,用"/"作为路径分隔符,而在Windows下是用"\",这往往给Tcl,乃至C语言,都带来了麻烦。因为在这两种语言里,"\"表示转义字符。如,\t是水平制表符,\n是换行符。幸运的是Windows也接受"/",所以,在Tcl和C里,你可以放心的用左斜杠"/"作为路径分隔符。但有些情况,你要注意一下转义序列
1、防止转义字符被解释的情况,如 \\
2、用花括号括起来的反斜杠路径路径名:{\foo\bar\grill.txt}
但Tc允许你在所有的情况用标准的分隔符"/",所有这样用你一般都比较安全的。Mac下就不行了,因为从MacOS开始,只接受冒号":"所为路径分隔符。
如果有必要的话,你可以这样来转换:
    % file normalize \\foo\\bar\\grill.txt
    C:/foo/bar/grill.txt
    % file nativename /foo/bar/grill.txt
    \foo\bar\grill.txt
还可以用 file join命令,如 file join arg1 arg2 ... argN,这时,Tcl会帮你考虑所有平台无关的细节,给你返回一个平台无关的路径。例如:
    set somepath [file join foo bar grill.txt]
    在Windows下将产生 foo/bar/grill.txt
   
输入输出

Tcl的输入输出命令几乎都非常接近C语言的stdio库里的命令(只不过去掉了开头的字符f):

set handle [open filename ?mode?]
set data [read $handle ?int?]
tell $handle
seek $handle offset ?from?
puts ?-nonewline? ?$handle? content
gets $handle ?varname?
close $handle
C里的printf命令的功能在Tcl里被分割成两个命令:
format,将数据转换成字符串(类似C的sprintf)
puts,输出结果为字符串,如:puts $handle [format "%05d %s" $number $text]

按行处理文本文件有两种方法,如果文件只有几个M,你可以一口气读完:
    set f [open $filename]
    foreach line [split [read $f] \n] {
    # work with $line here ...
    }
    close $f
文件稍大了,你只好一行一行的读,虽然相比之下,有点慢:
    set f [open $filename]
    while {[gets $f line] >= 0} {
    # work with $line here ...
    }
    close $f
最后,如果你想格式化你的文件,使之成为可以执行的Tcl代码,下面的命令最快
    source $filename
要touch一个文件,具体的说,如果文件不存在就新建,文件存在就更新其修改时间,可以这么做:
    proc touch name {close [open $name a]}

二进制文件
所有的文件都是由字节构成,字节又都是位,即二进制。文件的"二进制"是指那种字节可以是任何值的文件,而且行结束符(在DOS/Windows下,即是回车加换行)不被翻译过来。在Tcl里,可以很好的对二进制文件进行操作,只需要打开一个通道然后设置一下就行了:
    set fp [open tmp.jpg]
    fconfigure $fp -translation binary
    set content [read $fp]
    close $fp
运行上面的命令之后,变量content就存有文件的内容,每个字节都一样。
要检验一个文件是否是二进制文件,即是否存在空字节,可以这样,
    proc binary? filename {
   set f [open $filename]
   set data [read $f 1024]
   close $f
   expr {[string first \x00 $data]>=0}
    }
一些文件操作的命令:
很多有用的文件操作命令都集中在file命令下,file命令的第一个参数将告诉你要干什么

    * file atime name ?time?
    * file attributes name
    * file attributes name ?option?
    * file attributes name ?option value option value...?
    * file channels ?pattern? - returns the handles of currently open files
    * file copy ?-force? ?- -? source target
    * file copy ?-force? ?- -? source ?source ...? targetDir
    * file delete ?-force? ?- -? pathname ?pathname ... ?
    * file dirname name - e.g. [file dirname /foo/bar/grill.txt] -> /foo/bar
    * file executable name
    * file exists name
    * file extension name - e.g. [file extension /foo/bar/grill.txt] -> .txt
    * file isdirectory name
    * file isfile name
    * file join name ?name ...?
    * file link ?-linktype? linkName ?target?
    * file lstat name varName
    * file mkdir dir ?dir ...? - creates one or more directories (folders)
    * file mtime name ?time?
    * file nativename name
    * file normalize name
    * file owned name
    * file pathtype name
    * file readable name
    * file readlink name
    * file rename ?-force? ?- -? source target
    * file rename ?-force? ?- -? source ?source ...? targetDir
    * file rootname name - e.g. [file rootname /foo/bar/grill.txt] -> /foo/bar/grill
    * file separator ?name?
    * file size name
    * file split name - e.g [file split /foo/bar/grill.txt] -> {foo bar grill.txt}
    * file stat name varName
    * file system name
    * file tail name - e.g. [file tail /foo/bar/grill.txt] -> grill.txt
    * file type name
    * file volumes - Windows: returns your "drive letters", e.g {A:/ C:/}
    * file writable name

你可能感兴趣的:(TCL)