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
closeimmediately afteropen, 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.
Need an AutoCAD (AutoLISP, ObjectARX, .NET, VBA) development? Contact me for a free quote.