4

BufferedReader を使用してオブジェクトのストリーミング読み取りを実行しています。

このオブジェクトで 2 つのことを行う必要があります。

  1. SuperCSV csv リーダーに渡す
  2. 生の行を取得し、(Clojure) 遅延シーケンスに保持する

現在、2 つの異なる BufferedReaders を使用する必要があります。1 つは SuperCSV CSV リーダー クラスへの引数として、もう 1 つは生の行の遅延シーケンスを初期化するためです。S3 オブジェクトを効果的に 2 回ダウンロードしていますが、これは高価 ($) で低速です。

私の同僚の 1 人が、私が探しているのは Unix の「tee」コマンドに類似したものだと指摘しました。どういうわけか「分割」でき、データのチャンクをダウンロードし、コピーをレイジー シーケンスと csv リーダー機能の両方に渡すことができる BufferedReader が役立ちます。

また、遅延シーケンスを BufferedReader でラップして、それをスーパー csv に渡すことができるかどうかも現在調査中です。非常に大きな遅延シーケンスを複数のコンシューマーに渡すときに Java ヒープ スペースの問題が発生したので、この解決策を採用することを少し心配しています。

別の解決策は、ファイルをローカルにダウンロードしてから、このファイルで 2 つのストリームを開くことです。これにより、ストリーミングの背後にある本来の動機がなくなります。つまり、データが到着し始めるとすぐにファイルの処理を開始できます。

最終的な解決策であり、他に何も機能しない場合にのみ検討する解決策は、解析された CSV と元の解析されていない行の両方を返す独自の CSV リーダーを実装することです。解析された CSV データの Java ハッシュと元の解析されていない行の両方を返すことができる非常に堅牢な CSV リーダーを使用している場合は、お知らせください。

ありがとう!

4

2 に答える 2

2

ネットワークから一連の行を作成し、それをその seq で作業する必要がある多くのプロセスに引き渡す傾向があります。永続的なデータ構造はそのようにクールです。文字列のシーケンスを SuperCSV API に渡すことができる Reader に変換する必要がある場合、これはうまくいくようです:

(import '[java.io Reader StringReader])

(defn concat-reader
  「一連の文字列から読み取る Reader を返します。」
  [行]
  (let [srs (atom (map #(StringReader. %) lines)]]
    (プロキシ [リーダー] []
      (読んだ
        ([]
          (let [c (.read (最初の @srs))]
            (if (and (neg? c) (swap! srs next))
              (。これを読む)
              c)))
        ([cbuf]
          (.read this cbuf 0 (count cbuf)))
        ([cbuf オフレン]
          (let [実際の (.read (最初の @srs) cbuf off len)]
            (if (and (neg? actual) (swap! srs next))
              (.read this cbuf off len)
              実際))))
      (近い [] ))))

例えば

user=> (def r (concat-reader ["foo" "bar"]))
#'ユーザー/r
user=> (def cbuf (char-array 2))
#'ユーザー/cbuf
user=> (.read r cbuf)
2
ユーザー=> (seq cbuf)
(\f\o)
user=> (char (.read r))
\o
user=> (char (.read r))
\b
于 2010-08-27T03:22:19.217 に答える
0

解決策は、すべてのアクセスに単一の BufferedReader を使用し、最初から読み取る必要がある機能に渡されるたびにそれを reset() することでした。

于 2010-10-28T15:24:43.097 に答える