Writing to a file

<-Previous | ^UP^ | Next->

In the previous topic, we concluded by recomending that the CL macro with-open-file was used for any file input or output. So lets have a look at using this macro to write to a file

To write output to a file C:/temp/my-file.txt using with-open-file woud look like the following

GDL-USER>  (with-open-file (s "c:/temp/my-file.txt":direction :output:if-exists :supersede:if-does-not-exist :create)(format s "Line 1 of text~%")(format s "Line 1 of text~%")NIL

which will produce the following content in the file c:/temp/my-file.txt

Line 1 of textLine 1 of text

note that the stream s only exists within the context of the with-open-file body of expressions

In many cases, file output is implemented as a :function in a GendL object, although it is perfectly feasible to implement it as a side effect of a :computed-slot. Consider the following simple example

(define-object my-box (box):input-slots((output-filename "c:/temp/my-box-report")):computed-slots((width 3)(height 4)(length 6)):functions((write-report!()(with-open-file (s (the output-filename):direction :output:if-exists :supersede:if-does-not-exist :create)(let ((i 0))(format t "Begining output to ~a~%" (the output-filename))(format s "Box Width ~a~%" (the width))(incf i)(format s "Box Length ~a~%" (the length))(incf i)(format s "Box Height ~a~%" (the height))(incf i)(format s "Box Center ~@{~,1f~^,~}~%"(get-x (the center))(get-y (the center))(get-z (the center)))(incf i)(format s "Box Volume ~a~%" (the volume))(incf i)(format t "Output written (~a line~:p)~%" i)))))))

Here, as well as sending output to the stream connected to the file, we are also sending output to the REPL using the stream T (which defaults to *standard-output*. This is often a useful technique to assist with development and/or debugging. We could also write a small function which takes a filename as an input and executes the file output by calling the :function Write-report!

(defun output-report (fname)(let ((obj (make-object 'my-box:output-filename fname)))(theo obj write-report!)))

And then in the REPL we would see this

GDL-USER> (output-report "c:/temp/report.txt")

Begining output to c:/temp/report.txtOutput written (5 lines)NIL

Resulting in the file c:/temp/my-file.txt being written with the following content

Box Width 3Box Length 6Box Height 4Box Center 0.0,0.0,0.0Box Volume 72