Manipulating Files With Tcl
Manipulating Files With Tcl
Tcl provides a thin layer of abstraction over the Unix file system. I say thin because you can actually see Unix through it, but it's enough of an abstraction to be portable to most modern operating systems. (This is probably due to the success of C, which has resulted in most modern operating systems providing support for Unix style flat files.) Extended Tcl adds commands to provide direct access to Unix system calls, making the language suitable for systems programming.File Descriptors
Upon success, theopen
command returns a file descriptor or file identifier, which is a string. You should, in general, treat this string as a black box: you never need to look at it or print it, just sock it away in a variable to be passed as an argument to other commands. Standard File Descriptors
The Tcl interpreter makes the three standard Unix file descriptors available to your program. Standard input is available as the file descriptorstdin
; standard output is available as the file descriptor stdout
, and standard error is available as the file descriptor stderr
. The File Abstraction
Creating A File
A file is created implcitly in Tcl by opening it for writing. See below.Removing A File
Standard Tcl has no means to remove a file. It's easily accomplished, however, by invoking the external, standardrm
program: exec rm $filename
Extended Tcl has the unlink
command, which takes a variable number of arguments, which are file names, and removes them.
Opening a File
Theopen
command takes two arguments, a pathname and an (optional) access type. The pathname can of course be absolute or relative. open
supports two notations for the access method: both mimic different C library functions. If no second argument is given, the default is r
.
String-Style Access Method
A single string argument is used to indicate the access method, one of:r
- Read only, no create
r+
- Read / write, no create
w
- Write only, truncate or create
w+
- Read / write, truncate or create
a
- Write only, append or create
a+
- Read / write, append or create
List-Style Access Method
A list of any of the following flags may be provided as the second argument; exactly one ofRDONLY
, WRONLY
, or RDWR
must included in the list. RDONLY
- The file is opened for reading only.
WRONLY
- The file is opened for writing only.
RDWR
- The file is opened for reading and writing.
APPEND
- The file pointer is positioned at EOF before each write.
CREAT
- The file is created if it doesn't already exist.
EXCL
- Used with
CREAT
, generates an error if the does already exist (exclusive access). NONBLOCK
- Do not block when opening the file; generally only applies to fifos and sockets.
TRUNC
- If the file exists, truncate it to length zero upon open.
NOCTTY
- Do not become the controlling terminal (this one is fancy and can be ignored.)
No status code is returned to indicate success or failure: instead, any problems cause an error to be signalled.
Some examples:
# These first two are equivalent: set f [open /usr/dict/words r] set f [open /usr/dict/words] # So are these two: set tmpfile [open /tmp/temporary w] set tmpfile [open /tmp/temporary [list WRONLY CREAT TRUNC]]
Closing A File
All files are automatically closed when the process terminates, but sometimes you want to close files explictly. There are two typical reasons for this:- A process only has a finite number of file descriptors. In some Unixes there may be no limit, but in most modern Unix systems the limit is around 64. So if you're processing a huge number of files, even just serially, you want to be sure to close them as you go.
- Closing a file flushes buffers. If you want to be sure that the final buffer-full of data is flushed to disk as soon you're done writing, you should close the file. (But see Buffering below for finer control.)
The close
command just takes a file descriptor as an argument; an error is signalled if the file can't be closed or if it wasn't open.
Writing To A File
Theputs
command takes a file descriptor and a string, and writes the string to the file with a trailing newline added (unless the -nonewline option is given). If invoked with only one argument, the string is written to standard output. These two commands are equivalent: puts stdout "Foo" puts "Foo"
Reading From A File
Tcl has two commands for reading from a file:gets
is line-oriented, while read
is block oriented (and suitable for random access I/O). Extended Tcl adds some other commands: bsearch
searches a sorted file using binary search, and lgets
is list-oriented (it reads Tcl lists). The gets
Command
The gets
command comes in two flavors. The one-argument form takes a file descriptor as a parameter and returns the next line from the file. End of file is indicated as the empty string; since this is ambiguous, you may want to use the eof
command to test whether or not end of file actually occurred. More useful is the two-argument form, in which a variable name is provided as a parameter. In this form the next line read is stored in the named variable, and the length of the line is returned, or -1 or end of file.
In either form, the terminating newline is removed.
Here is a typical use of gets
in a loop to read an entire file line by line:
set f [open /home/keith/.profile] while {[gets $f line] >= 0} { puts [string length $line] } close $f
The read
Command
The read
command takes two parameters, a file descriptor and a count. The second parameter is optional. If provided, read
reads the next count bytes from the file (or up to end of file if there are fewer than count bytes left). The bytes are returned as a string. If the count argument is not provided, all the rest of the bytes in the file are read and returned. The bsearch
Command
The bsearch
command does a binary search of an open file. In its simplest form, it takes a file descriptor and a string to search for, and returns the matching line if found or the empty string. It also takes an optional variable name like gets
, in which case it returns a boolean value. (See TclX(7tcl) for complete details.) set f [open /usr/dict/words] bsearch $f zygote => zygote bsearch $f framistan => close $f
The lgets
Command
The lgets
command reads Tcl lists. It takes the same arguments as gets
, and returns results the same way, but reads Tcl lists rather than lines. Its easy to be confused by this command. In particular, the same way that it's a mistake to treat an arbitrary string as if it were a list, it's a mistake to use lgets
on a file that wasn't written full of lists by Tcl.
To write lists to a file in the form that lgets
will appreciate only requires that proper lists be written to the file with puts
. In this example, note the newline in the second list, which illustrates the difference between lgets
and gets
:
set f [open feh w] puts $f [list 1 2 3 4] puts $f [list foo bar \n baz] close $f set f [open feh r] while {[lgets $f l] >= 0} { puts [llength $l] } close $f
The eof
Command
The end of file status of any file descriptor can be tested at any time with the eof
command, which takes a file descriptor as an argument and returns a true (1) if end of file has been reached, or false (0) otherwise. Here is an alternate way to read all lines from a file, using eof: set f [open /home/keith/.profile] while {![eof $f]} { puts [string length [gets $f]] } close $f
Random Access
Tcl supports random access to files just like any other Unix programming language. The basic tools are:seek
to set the file pointer; tell
to read it; and read
to read a record. Note that any command that reads from a file can be used in a random access fashion; read
just usually makes more sense than gets
. Moving the File Pointer: Seeking In A File
seek fd offset ?origin?The
seek
command positions the file pointer for a given file descriptor fd to a specified byte offset. By default the offset is relative to the beginning of the file, but the optional origin parameter can be used to specify one of: start
(the beginning of the file)current
(the current file pointer)end
(the end of the file)
seek
always returns the empty string, so the only way to tell whether or not the seek suceeded is to use the tell
command and check if you got to where you were going. This is a Tcl design bug, especially given that the Unix seek system call returns the status.
Here is some code that reads a file of 80-column card images:
# Return the number of records of size $size in $fd proc number-of-records {size fd} { # Save current file pointer set fp [tell $fd] # Seek to eof seek $fd 0 end # Store file pointer set end [tell $fd] # Restore current file pointer seek $fd $fp if [expr $end % $size != 0] { error "not an integral number of records" } else { expr $end / $size } } set f [open cards] for {set n [number-of-records 80 $f]} {$n > 0} {incr n -1} { puts [string length [read $f 80]] } close $f
Querying the File Pointer
tell fdThe
tell
command returns the current position of the file pointer for file descriptor fd as an integer. Buffering
flush fdBy default, files opened for writing by Tcl are block buffered. You can actually control the buffering with Extended Tcl commands, but the simplest approach is to use the flush command after a write. Flushing is generally unnecessary when working with files (and in fact will slow you down), but it's crucial when doing IPC.
Current Working Directory
cd ?dirname? pwdThe
cd
command changes the current working directory (CWD) of the Tcl process to dirname (or to the user's home directory if dirname isn't given). The pwd
command returns the CWD as a string result. Reading Directories
globThe?-nocomplain?
?--?
pattern ?pattern ...?
glob
command provides easy access to the contents of directories. It takes the same glob patterns that we've seen before (e.g., in the switch
command) and applies them to the filenames stored in a directory, returning a list of the filenames that match. If there are no matching filenames, an error is signalled (unless -nocomplain
is specified). If the patterns are specified as absolute pathnames, the returned filenames will be absolute as well. The file
Command
The file
command gathers a number of miscellaneous file manipulation commands in one place. There are commands for manipulating file names, for checking the existance of a file, and for querying the inode. Manipulating File Names
file dirname name file extension name file rootname name file tail nameWhile Unix doesn't use mandatory filename extensions in the manner of MS/DOS, extensions are used conventionally, and so Tcl provides commands to manipulate them easily. A picture is worth a thousand words:
file dirname /a/b/foo.html => /a/b file extension /a/b/foo.html => .html file rootname /a/b/foo.html => /a/b/foo file tail /a/b/foo.html => foo.html
File Predicates
file exists name file owned name file executable name file readable name file writable name file isfile name file isdirectory nameThe
file
command provides several predicates for testing files. All return a Boolean (1 or 0) value. file readable
, file writable
, and file owned
test relative to the user running the Tcl script. Accessing The Inode
file stat name arrayname file type nameThe
file stat
command reads the inode for name and populates the array variable arrayname with entries for each field in the inode. The fields of the inode are named as follows:
nlink
- The link count.
uid
- The UID of the file's owner.
gid
- The GID of the file's group.
mode
- The mode of the file as a decimal (!) integer. This includes the user, group and other permissions, and also a few other bits (the setuid and setgid bits and the sticky bit).
size
- Size in bytes.
atime
- Last access time, as a decimal integer (seconds since the Unix epoch).
mtime
- Last modification time, as above.
ctime
- Last inode change time, as above.
ino
- The I-number.
dev
- The device the file resides on; together with the I-number, these these two values uniquely identify a file.
The file type
command returns a string which represents the type of the file, one of: file
, directory
, characterSpecial
, blockSpecial
, fifo
, link
, or socket
.
Accessing the Inode Via A File Descriptor
fstat fd fstat fd item fstat fd stat arrayvarExtended Tcl provides access to the contents of inodes via the
fstat
command. This command duplicates the file stat
command, except that while file stat
operates on a named file, fstat
operates on a file descriptor. fstat
comes in three flavors, each taking a mandatory file descriptor argument. In the first form, with no additional arguments, all the fields of the inode are returned as a keyed list. In the second form, only a specific value for the named field is returned, as a string. In the third form, all the fields are entered into the named array variable.
The fields of the inode are named as in the file stat
command; the following extra fields are provided:
type
- Type of file; possible values are:
file
,directory
,characterSpecial
,blockSpecial
,fifo
,link
, andsocket
. tty
- A boolean valuel, 1 if the file is a terminal.
remotehost
- This field is only present if the file descriptor refers to a network connection; in this case, the value is a list whose first element is the network address of the remote host and the second element is the hostname (if available).
http://www2.lib.uchicago.edu/keith/tcl-course/topics/tcl-files.html
相關文章
- TCL命令
- TCL 750評測 TCL 750值得買嗎?
- TCL - info命令
- Initialization Parameter Files and Server Parameter Files (287)Server
- Oracle FilesOracle
- tcl列表操作lsearch
- TCL集團改名為TCL科技(蘋果企業開發者賬號)蘋果
- TCL手機TCL 750正式釋出 售價1993元
- Java NIO filesJava
- Upload Files
- Paths和Files
- 智慧時代的TCL之舞
- Tcl語法簡介
- TCL學習之info命令
- TCL: LIST命令-lsearch, lsort, lrange
- TCL檔案查詢拆分
- 4.3.2.2.2 Oracle Managed FilesOracle
- JavaScript files 屬性JavaScript
- Reset and Checkout Files in GitGit
- Oracle Server Parameter FilesOracleServer
- PHP文字操作_FILESPHP
- TCL實業、TCL科技加入聯合國全球契約組織,攜手共建更好世界
- TCL: 變數和過程variable變數
- DataTransfer.files 屬性
- Special Characters in Initialization Parameter Files
- session_max_open_filesSession
- oracle-managed files (35)Oracle
- C# split big file into small files as, and merge the small files into big oneC#
- tcl/tk詳解——glob使用例解
- c++/tcl程式設計總結C++程式設計
- 使用Tcl操作Excel檔案的方法Excel
- Oracle DDL,DML,DCL,TCL 基礎概念Oracle
- tcl/tk參考——控制結構catch
- tcl/tk參考——控制結構errorError
- 2.5 Overview of Tablespaces and Database Files in a CDBViewDatabase
- nginx 修改 max open files limitsNginxMIT
- 解決 Too many symbol filesSymbol
- webstorm卡在scanning files to indexWebORMIndex