17. 파일 관련 함수

AutoLISP는 ASCII 코드의 텍스트 파일만을 지원하며, 더욱이 한 개의 파일에 대해서 Read와 Write를 동시에 지원하

지 않아 많은 제약이 따릅니다. 복잡한 데이터를 파일을 통해 처리할 때는 ObjectARX나 VBA를 사용하는 쪽이 훨씬

효율적이지만 항상 그러하듯이 잘만 사용하면 매우 유용하게 프로그램에 적용할 수가 있습니다.  하지만 요즘은 컴

퓨터 성능이 뛰어 나므로 LIST를 이용해서 처리하는 것도 훌륭한 대안이라 할 수 있겠습니다.

 

AutoLISP은 데이터 타입에 상관없이 파일 관련 함수를 통해서 불러온 모든 데이터는 문자열로 인식하므로 문자열

이외의 데이터(숫자, 리스트 등)를 파일에서 읽어 사용할 때는 변환 함수를 사용해서 변환을 해야 합니다.

데이터를 사용하지 않는다면 변환하지 않아도 무방하지만...........

파일에 기록을 할 때도 읽는 것과 마찬가지로 문자열만 기록할 수 있으며 문자열 이외의 데이터를 기록하고 싶을 때는

역시 변환 함수를 사용해서 변환을.......

이처럼 AutoLISP은 파일에서 읽거나  기록할 때  문자열만을 인식하기 때문에 파일 함수를 사용해서 프로그램을 할

수 있는 범위가 극히 제한 됩니다.

 

1. open

    (1) 기능

      사용자가 지정한 Mode에 따라 읽기 또는 쓰기 모드로 파일을 오픈하며, 파일을 성공적으로 오픈하면

      AutoCAD는 "File-Descriptor(파일 기술어)"를 반환합니다.

      "File-Descriptor"는 파일 종료시 반드시 필요하며, 고정적이지 않습니다.  따라서 반드시 [SETQ] 함수를 사용

      하여 저장하여하며 Read(Write)시와 파일 종료시 "File-Descriptor"를 지정해 주어야 합니다.

      주의 : [open] 함수는 위에서 설명했듯이 읽기와 쓰기, 추가 중에서 한가지 Mode로만 오픈이 가능합니다.

      Mode

      설                  명

      r

        읽기 전용으로 파일을 오픈합니다.

        만약, 파일이 존재하지 않으면 프로그램은 강제 종료됩니다.

      w

        파일을 쓰기 위해서 오픈합니다.

        만약, 파일이 존재하지 않으면 새로운 파일을 생성하며,  파일이 존재하면

        기존의 데이터는 지워지고 새로운 데이터가 덮어 쓰여집니다.

      a

        기존의 파일의 마지막에 데이터를 덧붙입니다.

        파일이 존재하면 기존의 데이터 끝에 새로운 데이터를 추가하며, 만약 파일

        이 존재하지 않으면 새로운 파일을 생성합니다.

     

    (2) 사용법

      (open "File-Name" "Mode")

      ** 참고

      "File-Name"에 디렉토리를 지정하려면 "/" 또는 "\\"를 사용해야 한다.([Load] 함수 참조)

       op.dat

       1 2 3 4 5 6 7 8 9 0

       Hello, LISP

       Sample File

 

    (3) 예제

      Open

      File-Descriptor(Return 값)

        (setq fileop1 (open "op.dat" "r"))

        :  <File: #344042e>

        (setq fileop2 (open "c:/op.dat" "w"))

        :  <File: #34403b0>

        (setq fileop3 (open "c:\\data\\op.dat" "a"))

        :  <File: #3313fd6>

        (setq fileop5 (open "c:/op.da" "r"))

        :   nil
        :   파일 오픈 실패시 "nil"을 반환

 

 

 

2. close

    (1) 기능

      "File-Descriptor"로 지정된 파일을 종료시키고 "nil"을 응답합니다.

      [close] 함수는 반드시 "File-Descriptor"를 포함해야 하며, "File-Descriptor"는 파일 Open시 얻을 수 있습니다.

       

    (2) 사용법

      (close File-Descriptor)

     

    (3) 예제

      Close

      Return 값

       (close fileop1)

        :  nil

       (close fileop5)

        :  error: bad argument type
           (CLOSE FILEOP5)
        : Open되어 있지 않는 파일이므로 에러가 발생합니다.

 

 

 

3. read-line

    (1) 기능

      키보드 또는 파일에서 문자열을 읽어들입니다.

      파일은 "File-Descriptor"로 지정되며, 지정된 파일에서 한 줄을 문자열로 읽어들입니다.

      한 줄을 읽은 다음 다시 "read-line"하면 자동으로 다음 줄을 읽으며, 파일의 끝에 도달하면 "nil"을 응답합니다.

      ** 참고

      ① [read-line] 함수를 사용하기 위해서는 먼저, 파일을 오픈(open)해야 합니다.

           만약, 파일이 종료(close)되거나, 오픈되어 있지 않으면 에러가 발생합니다.

      ②  List 형태로 저장되어 있는 파일을 읽어들여도 AutoLISP에서는 단일 문자열로 인식합니다.

     

    (2) 사용법

      (read-line "File-Descriptor")

     

    (3) 예제

       (setq rlnum1 (read-line fileop1))

       :  "1 2 3 4 5 6 7 8 9 0"

       (setq rlnum2 (read-line fileop1))

       :  "Hello, LISP"

       (setq rlnum3 (read-line fileop1))

       :  "Sample File"

       (setq rlnum4 (read-line fileop1))

       :  nil

       (setq rlnum5 (read-line fileop5))

      :  error: bad argument type

         (READ-LINE FILEOP5)

         (SETQ A (READ-LINE FILEOP5))

         *Cancel*

      :  Open되어 있지 않으므로 에러가 발생합니다.

 

    (4) 예제 프로그램

       

       ; SREAD.LSP

       (defun c:sread()

          (setq srl (open "c:/op.dat" "r"))

          (setq srl1 (read-line srl))

          (setq srl2 (read-line srl))

          (setq srl3 (read-line srl))

          (setq srl4 (read-line srl))

          (close srl)

       )

       

       Command: (load "c:/sread")
       C:SREAD

       Command: sread
       nil

       Command: !srl1
       "1 2 3 4 5 6 7 8 9 0"

       Command: !srl2
       "Hello, LISP"

       Command: !srl3
       "Sample File"

       Command: !srl4
       nil

       

 

 

 

4. read-char

    (1) 기능

      키보드 또는 파일에서 하나의 문자를 읽어 ASCII 코드로 출력합니다.

      "File-Descriptor"가 지정되어 있으면, 파일에서 하나의 문자를 읽어 ASCII 코드로 출력하며 "File-Descriptor"가

      지정되지 않으면, 사용자가 키보드로 입력하기를 기다립니다.

      [read-line] 함수와 같이 한 줄을 읽은 다음 다시 [read-char]하면 다음 라인을 읽습니다.

     

    (2) 사용법

      (read-char "File-Descriptor")

     

    (3) 예제

       (setq src1 (read-char fileop1))

       !src1   :   49

       (setq src2 (read-char fileop1))

       !src2   :   32

       (setq src3 (read-char fileop1))

       !src3   :   50

 

 

 

5. write-line

    (1) 기능

      화면 또는 파일에 문자열을 씁니다.

      쓰기 모드로 오픈된 "File-Descriptor"가 지정되어 있으면 파일에 문자열을 기록합니다.

      [write-line]은 개행문자(\n)를 포함하므로 자동으로 줄 바꿈이 일어납니다. 따라서, 기록되는 문자열은 별도

      로 개행문자(\n)을 포함할 필요가 없습니다.

       

    (2) 사용법

      (write-line "String" "File-Descriptor")

       

    (3) 예제

      (write-line "Smaple Write Line" fileop1)

      (setq swl "Test Write line")

      (write-line swl fileop1)

     

    (4) 예제 프로그램

       

       (defun c:swl()

          (setq swl (open "c:/swr.txt" "w"))

          (write-line "Sample Write Line" swl)

          (write-line "Test Write Line" swl)

          (close swl)

          (princ)

       )

       

      : SWR.TXT 파일

      Sample Write Line

      Test Write Line

         

 

 

 

6. write-char

    (1) 기능

      쓰기, 추가 모드로 오픈된 파일에 지정한 문자의 ASCII 코드 값을 기록합니다.

    (2) 사용법

      (write-char  Number  File-descriptor)

    (3) 예제

      (write 65 fileop1)

      (write 66 fileop1)

      (write 67 fileop1)

 

 

 

7. 예제 프로그램

    (1) 지정한 파일의 내용을 복사

     

     (defun c:cfile()

        (setq rfile (getstring "\n Enter Read File-Name : "))

        (setq wfile (getstring "\n Enter Output File-Name : "))

        (setq rf (open rfile "r"))

        (setq wf (open wfile "w"))

        (while

             (setq rline (read-line rf))

             (write-line rline wf)

        )

        (close rf)

        (close wf)

     )

     

 

    (2) 파일의 내용에서 사용자가 지정한 라인을 읽기

     

     (defun c:pread()

        (setq bard (getint "\n Enter Line Number : "))

        (setq barop (open "c:/ibar.dat" "r"))

        (repeat bard

              (setq barr (read-line barop))

        )

        (close barop)

     )

     

 

    (3) 선택한 PLine의 Vertex들을 파일에 기록

     

      X= -10.0000  Y= 238.0355  Z= 0.0000

      X=  -9.8000  Y= 238.1755  Z= 0.0000

      X=  -9.8000  Y= 238.1755  Z= 0.0000

      X=  -9.4000  Y= 238.4556  Z= 0.0000

      X=  -9.4000  Y= 238.4556  Z= 0.0000

                       ~

      X=   9.0000  Y= 238.7357  Z= 0.0000

      X=   9.4000  Y= 238.4556  Z= 0.0000

      X=   9.4000  Y= 238.4556  Z= 0.0000

      X=   9.8000  Y= 238.1755  Z= 0.0000

      X=   9.8000  Y= 238.1755  Z= 0.0000

     

    ;; 파일 : Pline2Vertex.LSP

    ;; 저장 : "X-Point  Y-Point"

    ;; 주의 : XY좌표 사이에 공백("  ")포함됨

     

    (defun c:ptov(/ object objlist cout wonso WFile FilePath)

       (setq object (car (entsel "\n PLine 선택 :")))

       (princ)

       (while (= object nil)

              (setq object (car (entsel "\n잘못된 선택입니다.\nPLine 선택 :")))

       )

       (setq objlist (entget object))

       (if (= (cdr (assoc 0 objlist)) "LWPOLYLINE")

           (progn

              (setq FilePath (getfiled "  좌표 저장 파일" "c:/Data/" "txt" 1))

              (setq WFile (open FilePath "w"))

              (setq count 0)

              (setq wonso (nth count objlist))

              (while (/= wonso nil)

                  (if (= (car wonso) 10)  ;; wonso = (10 xpoint ypoint)

                      (write-line (strcat (rtos (cadr wonso)) "  " (rtos (caddr wonso))) WFile)

                  )

                  (setq count (1+ count))

                  (setq wonso (nth count objlist))

              );while

              (close WFile)

           )

       )

       (princ)

    )

    적색 바탕의 라인은 XY 포인트를 분리하는 구분자를 공백(" ")으로 설정한 것입니다.

    만약 콤마(,)나 기타 다른 문자를 사용하고 싶다면 "   " 부분을 교체하면 됩니다.

    콤마 사용 예 :  (write-line (strcat (rtos (cadr wonso)) "," (rtos (caddr wonso))) WFile)

     

    (4) 선택한 파일의 Vertex로 PLine 그리기

     

     ;; 파일 : txt2line.lsp

     ;; Text : "X-Point  Y-Point"

     ;; 주의 : XY좌표 사이의 공백("    ")으로 분리함

     (defun c:toline(/ filePath fileid1 rline t_num xpoint ypoint)

        (setq FilePath (getfiled "  좌표 텍스트 파일 선택" "c:/" "" 2))

        (setq fileid1 (open FilePath "r"))

        (command "pline")

        (while

             (setq rline (read-line fileid1))

             (if (/= rline nil)

                 (progn

                    (setq t_num 1)

                    (while (<= t_num (strlen rline))

                       (if (= (substr rline t_num 1) " ")

                           (progn

                             (setq xpoint (substr rline 1 t_num))

                             (setq ypoint (substr rline (+ t_num 1) (strlen  rline)))

                           )

                       )

                       (setq t_num (+ t_num 1))

                    )

                    (command (list (atof xpoint) (atof ypoint)))

                 )

             )

        )

        (command "")

        (close fileid1)

        (princ)

     )

     

     

     -10  238.0355

     -9.8 238.1755

     -9.6 238.3156

     -9.4 238.4556

     -9.2 238.5956

     -9   238.7357

     -8.8 238.8757

     -8.6 239.0158

           ~

      8.8 238.8757

      9   238.7357

      9.2 238.5956

      9.4 238.4556

      9.6 238.3156

      9.8 238.1755

     10   238.0355

    위 프로그램은 3번 예제를 통해서 받아 저장한 좌표들로 PLine를 생성하는 프로그램입니다.

    적색 바탕의 라인은 구분자를 인식해서 XY 포인트를 분리하는 부분입니다.

    콤마나 기타 다른 구분자를 사용하였다면 3번 예제처럼 " " 부분을 동일하게 변경해주면 됩니다.

    콤마 사용 예 : (= (substr rline t_num 1) ",")

 

 

** File Descriptor?

    File Descriptor는 파일 관리를 위해 시스템이 필요로 하는 정보를 가지고 있습니다.

    일반적으로 File Descriptor에 포함되는 내용은 다음과 같습니다.

      ① 파일의 기호형 이름

      ② 보조 기억장치상의 파일 위치

      ③ 파일의 구조

      ④ 보조 기억 장치의 유형

      ⑤ 엑세스 제어 데이터

      ⑥ 파일의 유형

      ⑦ 제거시기

      ⑧ 생성시기

      ⑨ 최종 수정 시기

      ⑩ 엑세스 횟수

    위의 내용들은 다른 프로그램 언어에서 가지고 있는 내용입니다.

    AutoLISP에서는 어떤 내용을 가지고 있는지는 자료가 없어서...............

    아마도 거의 비슷한 내용을 가지고 있을 거라 생각됩니다.

 

 

 

변환 함수

최초 작성일 2000.02.08

Entity 함수

최종 수정일 2006.05.15