mirror of
https://github.com/penpot/penpot.git
synced 2026-09-05 19:49:11 +00:00
92 lines
3.0 KiB
Clojure
92 lines
3.0 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS INC Sucursal en España SL
|
|
|
|
(ns app.util.nio
|
|
"NIO helpers for working with files and byte arrays.
|
|
|
|
These are thin wrappers around java.nio that provide a
|
|
Clojure-idiomatic API. Candidates for porting to datoteka."
|
|
(:import
|
|
java.nio.ByteBuffer
|
|
java.nio.channels.FileChannel
|
|
java.nio.file.Files
|
|
java.nio.file.OpenOption
|
|
java.nio.file.Path
|
|
java.nio.file.StandardOpenOption))
|
|
|
|
(set! *warn-on-reflection* true)
|
|
|
|
;; ----------------------------------------------------------------
|
|
;; File operations (via java.nio.file.Files)
|
|
;; ----------------------------------------------------------------
|
|
|
|
(defn read-bytes
|
|
"Read all bytes from a file at `path`. Returns a byte array."
|
|
^bytes [^Path path]
|
|
(Files/readAllBytes path))
|
|
|
|
(defn write-bytes
|
|
"Write `data` (byte array) to a file at `path`, replacing existing
|
|
content. Returns `path`."
|
|
[^Path path ^bytes data]
|
|
(Files/write path data ^"[Ljava.nio.file.OpenOption;" (into-array OpenOption []))
|
|
path)
|
|
|
|
(defn append-bytes
|
|
"Append `data` (byte array) to the end of the file at `path`.
|
|
Creates the file if it does not exist. Returns `path`."
|
|
[^Path path ^bytes data]
|
|
(Files/write path data
|
|
^"[Ljava.nio.file.OpenOption;"
|
|
(into-array OpenOption
|
|
[StandardOpenOption/CREATE
|
|
StandardOpenOption/APPEND]))
|
|
path)
|
|
|
|
;; ----------------------------------------------------------------
|
|
;; FileChannel operations (internal API)
|
|
;; ----------------------------------------------------------------
|
|
|
|
(def ^:private read-write-opts
|
|
(into-array OpenOption
|
|
[StandardOpenOption/READ StandardOpenOption/WRITE]))
|
|
|
|
(defn open-channel
|
|
"Open a FileChannel for read/write on the given path."
|
|
^FileChannel [^Path path]
|
|
(FileChannel/open path read-write-opts))
|
|
|
|
(defn channel-size
|
|
"Return the size of the file backed by the channel."
|
|
^long [^FileChannel channel]
|
|
(.size channel))
|
|
|
|
(defn read-at
|
|
"Read `length` bytes from `channel` starting at `position` into a
|
|
new byte array. Returns the byte array.
|
|
Loops until the ByteBuffer is fully populated to guard against OS
|
|
partial reads, which would otherwise cause BufferUnderflowException
|
|
when copying from the buffer into the result array."
|
|
^bytes [^FileChannel channel ^long position ^long length]
|
|
(let [buf (ByteBuffer/allocate (int length))]
|
|
(.position channel position)
|
|
(loop []
|
|
(when (.hasRemaining buf)
|
|
(let [n (.read channel buf)]
|
|
(when (pos? n)
|
|
(recur)))))
|
|
(.flip buf)
|
|
(let [remaining (.remaining buf)
|
|
arr (byte-array remaining)]
|
|
(.get buf arr)
|
|
arr)))
|
|
|
|
(defn truncate
|
|
"Truncate the file to the given size. Returns the channel."
|
|
[^FileChannel channel ^long size]
|
|
(.truncate channel size)
|
|
channel)
|