2010-12-02 12 views
9

¿Cuál sería el mejor método para alinear un archivo en Clojure? No me he encontrado con utilidades que me ayuden a hacerlo, ¡pero las ideas sobre cómo construir una se apreciarán!¿Seguir un archivo en Clojure?

Gracias.

Respuesta

12

Como kotarak indicada, usted podría utilizar RandomAccessFile a buscar hasta el final del archivo. Lamentablemente, tiene que estar ocupado, esperar o dormir por los cambios.

Mediante una secuencia perezosa puede procesar las líneas "en la marcha":

(import java.io.RandomAccessFile) 

(defn raf-seq 
    [#^RandomAccessFile raf] 
    (if-let [line (.readLine raf)] 
    (lazy-seq (cons line (raf-seq raf))) 
    (do (Thread/sleep 1000) 
     (recur raf)))) 

(defn tail-seq [input] 
    (let [raf (RandomAccessFile. input "r")] 
    (.seek raf (.length raf)) 
    (raf-seq raf))) 

; Read the next 10 lines 
(take 10 (tail-seq "/var/log/mail.log")) 

Actualización:

Algo así como tail -f -n /var/log/mail.log 0, usando doseq, por lo que los cambios se consumen realmente.

(doseq [line (tail-seq "/var/log/mail.log")] (println line)) 
+0

¡Gracias por el puntero! Por alguna razón, esto no parece funcionar como se esperaba: ¡parece que los cambios de archivos no se detectan! – viksit

+0

(El programa se detiene después del primer cambio de archivo) – viksit

+0

Revise mi actualización: ¿También es posible que escribir en el archivo no esté "almacenado en la línea"? –

2

Algo así como:

(take-last 10 (line-seq (clojure.contrib.io/reader "file"))) 
3

Usted puede utilizar RandomAccessFile a buscar directamente al final del archivo y la búsqueda de saltos de línea a partir de ahí. No tan elegante y corto como el enfoque take-last, pero tampoco el O(n) que podría ser importante para archivos de gran tamaño.

Sin embargo, ninguna solución para tail -f. Puede encontrar algo de inspiración en JLogTailer.

Cuestiones relacionadas