AutoLISP: The Complete Guide — Chapter 11 / 16

Reading and Writing Files

AutoLISP isn't limited to manipulating the AutoCAD drawing. It can also read and write text files, which opens up many possibilities: exporting data, generating reports, reading configuration files, importing coordinates from a CSV file, and more.

Opening a file with open

The open function opens a file and returns a file descriptor that you'll use to read or write:

(setq file (open "C:/temp/my-file.txt" "r"))

The second argument is the open mode:

Mode Description
"r" Read — the file must exist
"w" Write — creates the file or overwrites its contents
"a" Append — creates the file or adds to the end

If the file cannot be opened (for example, it doesn't exist in "r" mode), open returns nil.

Reminder: in AutoLISP file paths, use forward slashes / (not backslashes \), or double the backslashes \\.

Writing to a file

write-line: writing a line

(setq file (open "C:/temp/export.txt" "w"))

(write-line "First line" file)
(write-line "Second line" file)
(write-line "Third line" file)

(close file)

Each call to write-line writes a line followed by an automatic line break. The resulting file will contain:

First line
Second line
Third line

princ and prin1: writing without a line break

If you need precise control over formatting, princ can write to a file without adding a line break:

(setq file (open "C:/temp/export.csv" "w"))

(princ "Name;X;Y;Z" file)
(princ "\n" file)  ; Manual line break
(princ "Point1;10.0;20.0;0.0" file)
(princ "\n" file)

(close file)

Never forget close

The close function is essential. If you don't close the file:

  • Data in the buffer may not be written to disk
  • The file remains locked by AutoCAD and cannot be opened by another program
  • You risk losing data

Best practice: always write close immediately after open, then add your code between the two. This way, you won't forget it.

Reading a file

read-line: reading a line

read-line reads the next line from the file and returns its content as a string. When there are no more lines to read, it returns nil:

(setq file (open "C:/temp/export.txt" "r"))

(read-line file)  ; → "First line"
(read-line file)  ; → "Second line"
(read-line file)  ; → "Third line"
(read-line file)  ; → nil (end of file)

(close file)

Reading all lines from a file

The classic pattern for reading an entire file:

(setq file (open "C:/temp/export.txt" "r"))
(setq line (read-line file))

(while line
  (princ (strcat "\n" line))  ; Process the line
  (setq line (read-line file))
)

(close file)

The while loop continues as long as read-line returns a string (i.e., as long as the end of the file hasn't been reached).

Practical example: exporting point coordinates

This program exports the coordinates of all points in the drawing to a CSV file:

(defun c:export-points (/ selection index entity data point file counter)
  (setq selection (ssget "_X" '((0 . "POINT"))))  ; Select all points

  (if selection
    (progn
      (setq file (open "C:/temp/points.csv" "w"))
      (write-line "X;Y;Z" file)  ; Header

      (setq index 0)
      (setq counter 0)
      (repeat (sslength selection)
        (setq entity (ssname selection index))
        (setq data (entget entity))
        (setq point (cdr (assoc 10 data)))

        (write-line
          (strcat
            (rtos (nth 0 point) 2 4) ";"
            (rtos (nth 1 point) 2 4) ";"
            (rtos (nth 2 point) 2 4)
          )
          file
        )

        (setq index (1+ index))
        (setq counter (1+ counter))
      )

      (close file)
      (princ (strcat "\n" (itoa counter) " point(s) exported to C:/temp/points.csv"))
    )
    (princ "\nNo points found in the drawing.")
  )
  (princ)
)

Practical example: importing points from a CSV

The reverse operation — reading a CSV file and creating points in the drawing:

(defun c:import-points (/ file line separator-position x y z counter)
  (setq file (open "C:/temp/points.csv" "r"))

  (if file
    (progn
      (read-line file)  ; Skip the header
      (setq line (read-line file))
      (setq counter 0)

      (while line
        ;; Split the line at the ";" separator
        (setq separator-position (vl-string-search ";" line))
        (setq x (atof (substr line 1 separator-position)))

        (setq line (substr line (+ separator-position 2)))
        (setq separator-position (vl-string-search ";" line))
        (setq y (atof (substr line 1 separator-position)))

        (setq z (atof (substr line (+ separator-position 2))))

        ;; Create the point
        (entmake
          (list
            '(0 . "POINT")
            (list 10 x y z)
          )
        )

        (setq counter (1+ counter))
        (setq line (read-line file))
      )

      (close file)
      (princ (strcat "\n" (itoa counter) " point(s) imported."))
    )
    (princ "\nUnable to open the file.")
  )
  (princ)
)

Searching for a file with findfile

The findfile function searches for a file in AutoCAD's support paths (those defined in Options, Files tab). If the file is found, it returns its full path. Otherwise, it returns nil:

(findfile "acad.pgp")      ; → "C:\\Program Files\\Autodesk\\AutoCAD 2026\\Support\\acad.pgp"
(findfile "my-file.lsp") ; → nil if the file is not in the support paths

This is very useful for locating configuration files or resources associated with your program, without having to hard-code an absolute path:

(defun load-configuration (/ path file line)
  (setq path (findfile "my-program.cfg"))
  (if path
    (progn
      (setq file (open path "r"))
      (setq line (read-line file))
      (while line
        (princ (strcat "\nConfig: " line))
        (setq line (read-line file))
      )
      (close file)
    )
    (princ "\nConfiguration file not found.")
  )
  (princ)
)

findfile also accepts a full path — in that case, it simply checks whether the file exists:

(if (findfile "C:/temp/data.csv")
  (princ "\nThe file exists.")
  (princ "\nThe file does not exist.")
)

Appending content to an existing file

The "a" (append) mode lets you add lines to the end of an existing file without overwriting its content:

(setq file (open "C:/temp/journal.log" "a"))
(write-line (strcat (rtos (getvar "CDATE") 2 6) " - Operation completed") file)
(close file)

This is handy for maintaining an activity log or accumulating data across multiple executions.

Summary

Function Role Example
open Open a file (open "file.txt" "r")
close Close a file (close file)
read-line Read a line (read-line file)
write-line Write a line (write-line "text" file)
princ Write without a line break (princ "text" file)
findfile Search for a file (findfile "acad.pgp")
Mode Description
"r" Read
"w" Write (overwrites)
"a" Append (to the end)

In the next chapter, we'll see how to handle errors with *error* to write robust programs that always restore their state, even when interrupted.


Helping hand Need an AutoCAD (AutoLISP, ObjectARX, .NET, VBA) development? Contact me for a free quote.