# Save your first file Save a three-byte attachment in an in-memory database, give it a name and read it back. This tutorial assumes you can use a Clojure REPL. It does not create files on disk. ## Start the REPL From an authorised xitstash checkout, with Java 17 or later, Clojure CLI and Babashka installed, run: ```shell bb javac clojure -Sdeps '{:deps {io.github.radarroark/xitdb {:mvn/version "0.48.0"}}}' -M ``` Wait for the `user=>` prompt. ## Load the library ```clojure (require '[ol.xitstash :as objects]) (import '[io.github.radarroark.xitdb CoreMemory Database Database$ContextFunction Hasher RandomAccessMemory ReadCountedHashMap WriteCountedHashMap] '[java.security MessageDigest]) ``` The `require` returns `nil`. The `import` returns `java.security.MessageDigest`. ## Save and read the attachment Evaluate the following expression. It prepares the content, commits a file named `note.bin` and returns the saved path and bytes: ```clojure (with-open [core (CoreMemory. (RandomAccessMemory.)) prepared (objects/prepare (byte-array [1 2 3]))] (let [db (Database. core (Hasher. (MessageDigest/getInstance "SHA-256")))] (locking db (.runContext db (reify Database$ContextFunction (run [_ root] (let [store (.putCursor (WriteCountedHashMap. root) "objects")] (objects/initialize! store) (objects/put! store prepared) (objects/create! store [{:name "note.bin" :digest (:digest prepared)}]))))) (let [store (.getCursor (ReadCountedHashMap. (.rootCursor db)) "objects") file (objects/lookup store 0 "note.bin")] (with-open [input (objects/open store (:digest file))] {:path (objects/path store (:id file)) :bytes (vec (.readAllBytes input))}))))) ``` Result: ```clojure {:path ["note.bin"] :bytes [1 2 3]} ``` The file lives below catalog root `0`. Its bytes were prepared before the transaction and read after the commit. The enclosing `with-open` forms close the stream, prepared content and memory database. Run the expression again. It creates a fresh database and returns the same result. ## Next Use [xitdb-clj transactions](xitdb-clj.adoc) to save attachments alongside Clojure application records. Read [Content and history](content-and-history.adoc) for the distinction between a file name and a payload.