私はdocjureを使ってExcelファイルに書き込んでいます。ほとんどの場合、既存のファイルに行を追加します。通常は一度に 1 行です。エージェント/フューチャーなしでこれを行う場合、ファイルをロードし、add-rows を使用してデータを追加し、次のようにファイルを書き換えます。
(defn append [filename data]
"data is in the same format as create-workbook, i.e. [[\"n\" \"m\"] [1 2] [3 4]]"
(let [workbook (load-workbook filename))
sheet (select-sheet workbook "Sheet1")]
(add-rows! sheet data)
(save-workbook! filename workbook)))
私はappendするために多くの呼び出しを行うので、これを見つけました:http://blakesmith.me/2012/05/25/understanding-clojure-concurrency-part-2.html、エージェントを使用して書き込む方法を示していますfuture を使用するファイル。
まず第一に、FileWriter の代わりに FileOutputStream を使用していますが、これは引き続き機能しますが、チュートリアルの例では、.write を使用してファイルの末尾に文字列を追加してから閉じるだけで、毎回ファイルを書き直す必要があります。 .xlsx ワークブックには、単なる文字よりも多くのバイトがあるため、「追加」(と思いますか?) します。
チュートリアルのロギングの例では、write-out は BufferedWriter の更新されたインスタンスを返し、それに相当するものがわからないため、これを設定する方法がよくわかりません。
私の他のオプションは、データをベクターに同時に追加することです(ファイルを一度ロードし、データが追加された新しいベクター [[\"n\" \"m\"] [1 2] [3 4]] を返し続けます)しかし、私はこれらの呼び出しを〜10000〜100000回行うことを計画しており、追跡するのは大変なようです...ただし、すべてのデータを何度も読み書きするのはおそらくそれほど素晴らしいことではありません.
これを行う方法について何か提案があれば、よろしくお願いします。それを追加するより良い方法があれば、Apache POI自体にも喜んで呼び出しを行います。ありがとう。
--- UDPATE ---
出力ストリームではなくエージェントとしてファイルを使用してロガーの例を書き直したところ、うまくいくようです。docjure/Apache POI で動作するようになったらお知らせします。
(def logfile (agent (File. "blah.txt")))
(defn write-out [file msg]
(with-open [out (BufferedWriter. (FileWriter. file true))]
(.write out msg))
file)
--- UDPATE 2 ---
私はdocjureで書かれた類似のバージョンを手に入れましたが、残念なことに、ファイルを開くことは書き込み中に起こり、それはそれぞれの未来の間に起こります(私がエージェントとしてファイルを使用する場合、これを回避する方法はわかりません。それ以外の別の方法を参照してください)それらのほとんどは空のファイルを読み取り、それに行を書き込みます。それらはすべて並行して行われ、最終結果はそれらのほとんどが互いに上書きすることです.
最終的に、各行ベクトルを全体的なデータ ベクトルに追加して、1 回書き込むことにしました。pmapだけでそれを行うことができるので、ずっときれいです。1 つの欠点は、何か問題が発生した場合にデータがまったくファイルに書き込まれないことですが、書き込み呼び出しが 1 回しかないため、書き込みにかかる時間が短縮されるという利点があります。また、大量のデータを毎回メモリにロードしていたので、時間がかかりました。どちらの方法でもメモリ使用量は同じです。
誰かがまだこれに答えたいと思っているなら、私はまだ興味がありますが、最初の更新の方法は機能しません (それぞれの将来は空のファイルを読み取り、それを使用して追加します)。誰にでも役立つ場合に備えて、そのコードを投稿します-前述のチュートリアルのdocjureバージョン:
(def file (agent (File. "blah.xlsx")))
(defn write-out [file workbook]
(with-open [out (FileOutputStream. file)]
(.write workbook out))
file)
(defn write-workbook [file data]
(let [filename (.getPath @file)
workbook (try (load-workbook filename)
(catch Exception e (create-workbook "Sheet1" [])))
sheet (select-sheet "Sheet1" workbook)]
(add-rows! sheet data)
(send file write-out workbook)))
(defn test [file]
(write-workbook file [["n" "m"]])
(dotimes [i 5]
(future (write-workbook file [[i (inc i)]]))))
ありがとう