2012-07-06 9 views
6

Estoy creando un servidor de archivos estáticos en Clojure con Compojure y estoy atascado al leer una imagen del sistema de archivos y mostrar esa imagen a través de una ruta Compojure.¿Cómo se puede leer el contenido de un archivo binario en una cadena en Clojure?

slurp lamentablemente no maneja datos binarios muy bien, y lo he intentado estos 100 maneras diferentes desde entonces, pero este es mi último intento fallido:

(defn image-output [filepath] 
    (try 
    (let [contents (apply str (with-open [rdr (io/reader filepath)] 
     (into #{} (line-seq rdr))))] 
     { 
     :status 200 
     :headers 
     { 
      "Content-Type" "image/jpeg", 
      "Content-Length" "", 
      "Cache-Control" "", 
      "Expires" "" 
     } 
     :body contents 
     })) 
    (catch Exception e {:status 404}))) 

(defn endpoint_view [params] 
    (if (contains? params :bucket) 
    (image-output (join "/" [data_path (:bucket params) (:dir params) (:filename params)])))) 

(defroutes main-routes 
    (GET "/view/:bucket/:dir/:filename" {params :params} (endpoint_view params)) 
    (route/files "/") 
    (route/resources "/s" {:root "./public/s"}) 
    (route/not-found "Page not found")) 

parece este intento actual sufre el mismo destino como usar slurp, donde puedo repetir la cadena de contenido y su cadena codificada, pero cuando cambio el tipo de contenido a image/jpeg es una imagen rota.

Pasé todo el día ayer buscando en Google, pero ninguno de los ejemplos logró el mismo objetivo, y aunque me ayudaron a entender un poco más sobre Java IO, no fueron lo suficientemente claros como para ayudarme a llegar a donde tenía que ir , o produjo los mismos resultados que ya obtenía (ejemplo: Best way to read contents of file into a set in Clojure).

(! Puntos de bonificación Imaginario si me puede decir cómo llegar al tipo de contenido de la ruta de archivo, así como que es mi siguiente pregunta)

Respuesta

7

Simplemente hacer que el cuerpo sea (io/file filepath) - Ring es perfectamente feliz para servir archivos de tú.

Editar para obtener puntos de bonificación: puede usar ring.middleware.file-info/wrap-file-info para obtener metadatos de archivos para los archivos que devuelve. O bien, podría servir un directorio completo con (compojure.route/files "/public"), que hace todo este lío por usted.

+1

Bueno maldición. ¡Estás en lo correcto, señor! Todavía estaría interesado en saber cómo leer datos binarios en una cadena aunque como maté un día tratando de resolverlo, pero esto resuelve mi problema inmediato. ¡Gracias! –

+3

No lo hagas. Las cadenas no son binarias, nada bueno saldrá de esto. – amalloy

Cuestiones relacionadas