Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Reid G.C.Thinking in PostScript.1990.pdf
Скачиваний:
17
Добавлен:
23.08.2013
Размер:
846.44 Кб
Скачать

READING AND WRITING FILES

Once you have a valid file object, either from the file operator or the currentfile operator, you can read from it or write to it any number of times (or at least until you run out of data to read or until you fill up the file system).

The read operator (and its variants) returns an exit status boolean to let you know whether or not it succeeded. This lends itself nicely to an ifelse statement for error checking, unless you are very sure that the operation will succeed and you want the code to execute as fast as it can (which is, actually, fairly often the case).

Reading from a File

There are several PostScript operators that you can use to read from a file object. All but one require you to provide a buffer into which the operator can place the bytes read from the file. The exception is the read operator; it just reads a single byte from a file, and therefore it doesn’t need a buffer. The size of the buffer is up to you. Most of the read operations in PostScript will simply read until they fill up your buffer. In contrast, the readline operator reads until it sees a specific end-of-line condition. This can create two possible error conditions.

1.You might run out of data to read before you fill your buffer.

2.You might run out of buffer space before you get to an end-of- line condition.

If you run out of data before the buffer is full, the operator you were using to read from the file will tell you (by leaving false on the stack). There is no general way to make sure that your use of readline won’t overflow your buffer. If you’re worried about it, you can certainly use a very large buffer (some implementations limit string sizes to about 64 kilobytes).

Example 14.4 illustrates use of the readstring operator to read data from a file and write it to a new file.

Writing to a File

Writing to a file is very similar to reading from a file, with a couple of exceptions. First of all, the writing operators do not return a boolean

172

Chapter 14: USING FILES AND INPUT/OUTPUT TECHNIQUES

indicating their success or failure. And second, there are a few special character string conventions for such things as newlines and parentheses that apply to strings that you write to a file (detailed in Table 14.4).

Table 14.4: Special Characters

In String Body

Actual Character

\n

newline

\r

return character

\t

tab

\b

backspace

\f

form feed

\\backslash

\(

left parenthesis

\)

right parenthesis

\XXX

three-digit octal character code, such as \037

\a backslash followed by a newline indicates

no character, and is used to continue a long line

to avoid problems in environments where line lengths are restricted

The most common operator for writing to a file is the writestring operator, which takes an arbitrary string and writes it to the file object you supply. The string is written exactly, byte for byte, to the output file, with the exception of the special backslash escapes. In particular, writestring does not automatically add a newline or carriage return to each line of text written to the file. (If you want a newline, just put \n at the end of your string before you call writestring.)

The program in Example 14.3 writes the StandardEncoding array out to a temporary file.

Example 14.3: Writing an Array Out to a File

/tmpfile (/user/glenn/encoding.ps) (w) file def /scratch 128 string def

tmpfile (/StandardEncoding [ \n) writestring StandardEncoding { %forall

tmpfile ( /) writestring

tmpfile exch scratch cvs writestring tmpfile (\n) writestring

} forall

tmpfile (] def\n) writestring tmpfile closefile

Chapter 14: USING FILES AND INPUT/OUTPUT TECHNIQUES

173

Copying and Renaming Files

In order to copy a file, you need to open it with mode (r), open the destination file with mode (w), and use the loop operator to read from one file and write to the other until you reach the end of the input file. Example 14.4 copies the file (/etc/passwd) to a new file named (/etc/passwd.BAK). It assumes that the original file already exists and can be opened for reading.

Remember to write out the last partial buffer. When the readstring operator returns false, there may be a few bytes in the substring that were read before the end-of-file indication was encountered. This can be seen in the else clause of the conditional in Example 14.4. The contents of the string are written before the files are closed and before the loop is finally exited.

Example 14.4: Copying a File

/infile (/etc/passwd) (r) file def

% open files and save file objects

/outfile (/etc/passwd.BAK) (w) file def

 

/buff 128 string def

% your buffer for reading operations

{ % loop

 

infile buff readstring { %ifelse

 

outfile exch writestring

 

}{ %else

 

outfile exch writestring

 

infile closefile

 

outfile closefile

 

exit % exit the loop

 

} ifelse

 

} bind loop

 

To rename a file, simply use the renamefile PostScript operator if it exists. The program in Example 14.5 checks for the existence of renamefile and if it is not found, it defines a procedure called renamefile that emulates the behavior of the operator by copying the file to the new name and then deleting the original file.

174

Chapter 14: USING FILES AND INPUT/OUTPUT TECHNIQUES