:TITLE: File Access 101 ;# ;# RCSID: $Header: /cvsroot/tcl/tcltutorial/original/Tcl24.lsn,v 1.1 2004/11/04 16:01:14 davidw Exp $ ;# Copyright (c) 1995 Clif Flynt ;# 9300 Fleming Rd. ;# Dexter, MI 48130 ;# clif@cflynt.com ;# See file "NOTICE" for licensing terms. ;# ::CMD:: if {([info exists tcl_platform])} { switch $tcl_platform(platform) { unix { set Tutor(lsn.codeMod) { } } windows { set Tutor(lsn.codeMod) { {if {[glob -nocomplain C:/temp] != ""} { regsub "/tmp" $line "/temp" line } } {if {[glob -nocomplain C:/windows/temp] != ""} { regsub "/tmp" $line "/windows/temp" line } } {if {[glob -nocomplain C:/winnt/temp] != ""} { regsub "/tmp" $line "/winnt/temp" line } } } } mac { set Tutor(lsn.codeMod) { } } default { puts "I don't recognize the platform: $tcl_platform(platform)" puts "Can't set platform specific parameters" } } } :LESSON_TEXT_START_LEVEL 0: Tcl supports an interface to the file system using the buffered i/o mechanism.

The simplest methods to access a file are via gets and puts. When there is a lot of data to be read, however, it is sometimes more efficient to use the read command to load an entire file, and then parse the file into lines with the split command.

open fileName ?access? ?permission?
Opens a file and returns a token to be used when accessing the file via gets, puts, close, etc.
close fileID
Closes a file previously opened with open, and flushes any remaining output.
gets fileID ?varName?
Reads a line of input from FileID, and discards the terminating newline.

If there is a varName argument, gets returns the number of characters read (or -1 if an EOF occurs), and places the line of input in varName.

If varName is not specified, gets returns the line of input. An empty string will be returned if:

puts ?-nonewline? ?fileID? string
Writes the characters in string to the stream referenced by fileID.

FileID is one of:

read ?-nonewline? fileID
Reads all the remaining bytes from fileID, and returns that string. If -nonewline is set, then the last character will be discarded if it is a newline. Any existing end of file condition is cleared before the read command is executed.
read fileID numBytes
Reads up to numBytes from fileID, and returns the input as a Tcl string. Any existing end of file condition is cleared before the read command is executed.
seek fileID offset ?origin?
Change the current position within the file referenced by fileID. Note that if the file was opened with "a" access that the current position can not be set before the end of the file for writing, but can be set to the beginning of the file for reading.
tell fileID
Returns the position of the access pointer in fileID as a decimal string.
flush fileID
Flushes any output that has been buffered for fileID.
eof fileID
returns 1 if an End Of File condition exists, otherwise returns 0.
:TEXT_END: :LESSON_TEXT_START_LEVEL 1: Tcl supports an interface to the file system using the buffered i/o mechanism.

The simplest methods to access a file are via gets and puts. When there is a lot of data to be read, however, it is sometimes more efficient to use the read command to load an entire file, and then parse the file into lines with the split command.

open fileName ?access? ?permission?
Opens a file and returns a token to be used when accessing the file via gets, puts, close, etc.
close fileID
Closes a file previously opened with open, and flushes any remaining output.
gets fileID ?varName?
Reads a line of input from FileID, and discards the terminating newline.

If there is a varName argument, gets returns the number of characters read (or -1 if an EOF occurs), and places the line of input in varName.

If varName is not specified, gets returns the line of input. An empty string will be returned if:

puts ?-nonewline? ?fileID? string
Writes the characters in string to the stream referenced by fileID.

FileID is one of:

read ?-nonewline? fileID
Reads all the remaining bytes from fileID, and returns that string. If -nonewline is set, then the last character will be discarded if it is a newline. Any existing end of file condition is cleared before the read command is executed.
read fileID numBytes
Reads up to numBytes from fileID, and returns the input as a Tcl string. Any existing end of file condition is cleared before the read command is executed.
seek fileID offset ?origin?
Change the current position within the file referenced by fileID. Note that if the file was opened with "a" access that the current position can not be set before the end of the file for writing, but can be set to the beginning of the file for reading.
tell fileID
Returns the position of the access pointer in fileID as a decimal string.
flush fileID
Flushes any output that has been buffered for fileID.
eof fileID
returns 1 if an End Of File condition exists, otherwise returns 0.

Points to remember about Tcl file access:

:TEXT_END: :LESSON_TEXT_START_LEVEL 2: Tcl supports an interface to the file system using the buffered i/o mechanism. This mechanism treats the file like a stream of characters that start at the beginning of the file, and run one after the other to the end. This makes a file look the same as a terminal to the program, and a program can write a line of input to a file with the same puts command (but with one new argument) that is used to print text to the screen. Data can be read from a file with a gets, just as it can be read from a keyboard.

Before a file can be accessed in this manner the program has to declare which file is to be accessed, and whether it is to be accessed for reading, writing, or both. This declaration is made with the open command. Once the file is opened, the program can execute gets and puts calls to read or write lines of data from or to the file.

A program can also use a seek command to position a marker within the file. After the marker has been placed, the next gets or puts will occur from that location.

When a program is finished with a file, it should close the file. There are a finite number of open file descriptor slots available for a program, and if you neglect to close files, you may find your program failing when it runs out of descriptor slots.

The file access commands are:

open fileName ?access? ?permission?
Opens a file and returns a token to be used when accessing the file via gets, puts, close, etc.
close fileID
Closes a file previously opened with open, and flushes any remaining output.
gets fileID ?varName?
Reads a line of input from FileID, and discards the terminating newline.

Fileid is one of:

If there is a varName argument, gets returns the number of characters read (or -1 if an EOF occurs), and places the line of input in varName.

If varName is not specified, gets returns the line of input. An empty string will be returned if:

puts ?-nonewline? ?fileID? string
Writes the characters in string to the stream referenced by fileID.

FileID is one of:

read ?-nonewline? fileID
Reads all the remaining bytes from fileID, and returns that string. If -nonewline is set, then the last character will be discarded if it is a newline. Any existing end of file condition is cleared before the read command is executed.
read fileID numBytes
Reads up to numBytes from fileID, and returns the input as a Tcl string. Any existing end of file condition is cleared before the read command is executed.
seek fileID offset ?origin?
Change the current position within the file referenced by fileID. Note that if the file was opened with "a" access that the current position can not be set before the end of the file for writing, but can be set to the beginning of the file for reading.
tell fileID
Returns the position of the access pointer in fileID as a decimal string.
flush fileID
Flushes any output that has been buffered for fileID.
eof fileID
returns 1 if an End Of File condition exists, otherwise returns 0.

Points to remember about Tcl file access:

:TEXT_END: :CODE_START: set fileid [open "/tmp/testfile" w+] seek $fileid 0 start puts $fileid "This is a test.\nIt is only a test" seek $fileid 0 start set chars [gets $fileid line1]; set line2 [gets $fileid]; puts "There are $chars characters in \"$line1\"" puts "The second line in the file is: \"$line2\"" seek $fileid 0 start set buffer [read $fileid]; puts "\nTotal contents of the file are:\n$buffer" close $fileid :TEXT_END: