Created
September 9, 2018 15:28
-
-
Save mfikes/03172ce8dd62439431026b7b94ec201f to your computer and use it in GitHub Desktop.
Async file io in Clojure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns api-server.file-io | |
(:use [clojure.tools.logging :only (info warn error)]) | |
(:import (java.nio.channels CompletionHandler AsynchronousFileChannel) | |
(java.nio ByteBuffer) | |
(java.nio.file.attribute FileAttribute) | |
(java.nio.file StandardOpenOption) | |
(java.util.concurrent Executors)) | |
(:require [clojure.core.async :as async :refer [chan go put! close!]] | |
[clojure.java.io :as io])) | |
(def asynch-file-executor (Executors/newFixedThreadPool 8)) | |
(defn file-exits!? | |
[file] | |
(.exists (io/as-file file))) | |
(defn- file-uri | |
[file] | |
(.toURI (io/as-file file))) | |
(defn read-file! | |
[file] | |
(let [ch (chan) | |
path (java.nio.file.Paths/get (file-uri file)) | |
fileChannel (AsynchronousFileChannel/open path #{StandardOpenOption/READ} asynch-file-executor (make-array FileAttribute 0)) | |
buffer (ByteBuffer/allocate (.size fileChannel))] | |
(.read fileChannel buffer 0 nil | |
(proxy [CompletionHandler] [] | |
(completed [result attachment] | |
(.close fileChannel) | |
(.flip buffer) | |
(put! ch buffer)) | |
(failed [e attachment] | |
(.close fileChannel) | |
(put! ch e)))) | |
ch)) | |
(defn write-file! | |
[file buffer] | |
(let [ch (chan)] | |
(try | |
(let [path (java.nio.file.Paths/get (file-uri file)) | |
fileChannel (AsynchronousFileChannel/open path #{StandardOpenOption/WRITE} asynch-file-executor (make-array FileAttribute 0))] | |
(.write fileChannel buffer 0 nil | |
(proxy [CompletionHandler] [] | |
(completed [result attachment] | |
(.close fileChannel) | |
(close! ch)) | |
(failed [e attachment] | |
(.close fileChannel) | |
(put! ch e))))) | |
(catch Throwable t | |
(warn t "Failed writing file" file) | |
(put! ch t))) | |
ch)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment