2010-09-28 11 views

risposta

14

Come su

(defun get-file (filename) 
    (with-open-file (stream filename) 
    (loop for line = (read-line stream nil) 
      while line 
      collect line))) 
+0

(con-open-file di (f filename) Perché hai un f prima di nome di file lì? cosa fa la linea di raccolta? E in che modo collabora alla fine della linea? – Sterling

+3

'with-open-file' apre il file chiamato' filename' e associa lo stream con 'f'. 'collecting' raccoglie i vari valori di' line' in una lista, fino a quando 'while' è' nil'. Common Lisp HyperSpec e Practical Common Lisp sono i tuoi amici! –

+2

In altre parole, 'with-open-file' fa tutto il lavoro di' open' e 'close' e' let'. –

8

Dove sono i problemi?

(defun get-file (filename) 
    (let ((x (open filename))) 
    (when x 
     (loop for line = (read-line x nil) 
      while line 
      do (list line))) ; <-- you are not collecting, just doing 
    (close x)))     ; <- the function returns the value of CLOSE 

(defun get-file (filename) 
    (let ((x (open filename :if-does-not-exist nil)) 
     (contents (list nil))) 
    (when x 
     (loop for line = (read-line x nil) 
      while line 
      do (cons contents line))) ; <-- again, the cons goes nowhere 
    (close x) contents))    ; <-- CONTENTS has never been changed 

(defun get-file (filename) 
    (let ((x (open filename :if-does-not-exist nil)) 
     (contents nil)) 
    (when x 
     (loop for line = (read-line x nil) 
      while line 
      do (append contents line))) ; <- again the result goes nowhere 
    (close x) contents))     ; <-- CONTENTS has never been changed 

DO eseguirà solo qualcosa per gli effetti collaterali.

COLLECT raccoglierà il risultato e LOOP quindi restituirà un elenco di valori raccolti all'uscita.

Come già accennato, utilizzare WITH-OPEN-FILE anziché OPEN/CLOSE. WITH-OPEN-FILE chiuderà il file lasciando l'ambito dinamico. Non solo da una normale uscita, ma anche da condizioni di errore usando UNWIND-PROTECT.

Se si desidera leggere il contenuto di un file, è possibile utilizzare READ-SEQUENCE. Con i soliti problemi. Ad esempio quando si legge un file ASCII come testo in una stringa, la stringa potrebbe essere più corta del file. Ad esempio Common Lisp rappresenterà internamente CRLF con un singolo carattere, su piattaforme in cui CRLF è newline. Un altro esempio: nelle implementazioni di supporto Unicode, il codice UTF-8 nel file può essere sostituito con un singolo carattere.

+0

+1 per la descrizione degli errori! –

Problemi correlati