4

我正在使用 BufferedReader 对对象执行流式读取。

我需要对这个对象做两件事:

  1. 将其传递给 SuperCSV csv 阅读器
  2. 获取原始行并将它们保存在(Clojure)惰性序列中

目前,我不得不使用两种不同的 BufferedReader:一种作为 SuperCSV CSV 阅读器类的参数,另一种用于初始化原始行的惰性序列。我有效地下载了 S3 对象两次,这很昂贵($)而且速度很慢。

我的一位同事指出,我正在寻找类似于 Unix“tee”命令的东西。一个 BufferedReader 可以以某种方式“拆分”,下载一大块数据,并将副本传递给惰性序列和 csv 阅读器功能将很有用。

我目前也在研究是否可以将惰性序列包装在 BufferedReader 中并将其传递超级 csv。在将非常大的惰性序列传递给多个消费者时,我遇到了一些 Java 堆空间问题,所以我有点担心采用这种解决方案。

另一种解决方案是在本地下载文件,然后在该文件上打开两个流。这消除了流式传输背后的原始动机:允许在数据开始到达时立即开始处理文件。

最终的解决方案,也是我只有在没有其他方法的情况下才会考虑的解决方案,是实现我自己的 CSV 阅读器,它返回已解析的 CSV 和原始的未解析行。如果您使用了一个非常可靠的 CSV 阅读器,它可以返回已解析 CSV 数据的 Java Hash 和原始未解析行,请告诉我!

谢谢!

4

2 回答 2

2

我倾向于从网络创建一个序列,然后将其交给需要处理该序列的许多进程;持久化数据结构很酷。如果需要将一系列字符串转换为可以交给 SuperCSV api 的 Reader,这似乎可行:

(导入'[java.io Reader StringReader])

(定义连接阅读器
  “返回一个读取字符串序列的阅读器。”
  [线]
  (让 [srs (atom (map #(StringReader.%) 行))]
    (代理 [读者] []
      (读
        ([]
          (让 [c (.read (first @srs))]
            (if (and (neg?c) (swap! srs next))
              (。读这个)
              C)))
        ([cbuf]
          (.read this cbuf 0 (count cbuf)))
        ([cbuf 关闭 len]
          (让 [实际 (.read (first @srs) cbuf off len)]
            (如果(和(否定?实际)(交换!下一个 srs))
              (.read this cbuf off len)
              实际的))))
      (关闭 [] ))))

例如

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

解决方案是对所有访问使用单个 BufferedReader,然后在每次将其传递到需要从头开始读取的功能时对其进行重置()。

于 2010-10-28T15:24:43.097 回答