在scala中将文件分块为多个流

时间:2018-09-07 19:54:43

标签: scala file bufferedreader

我的程序中有一个用例,需要提取一个文件,将其平均分割N次,然后远程上传。

我想要一个接受File并输出BufferedReader列表的函数。我可以将它们分发给它们,然后将其发送到另一个使用某些API存储它们的函数。

我已经看到了一些示例,其中的作者利用了.lines()的{​​{1}}方法:

BufferedReader

我想上面的例子可以用,虽然不漂亮但是可以用。

我的问题:

  • 是否可以将def splitFile: List[Stream] = { val temp = "Test mocked file contents\nTest" val is = new ByteArrayInputStream(lolz.getBytes) val br = new BufferedReader(new InputStreamReader(is)) // Chunk the file into two sort-of equal parts. // Stream 1 val test = br.lines().skip(1).limit(1) // Stream 2 val test2 = br.lines().skip(2).limit(1) List(test, test2) } 分成多个流列表?
  • 我无法控制BufferedReader的格式,因此文件内容可能只有一行。那不是仅仅意味着File会将所有内容加载到一个元素的.lines()中吗?

2 个答案:

答案 0 :(得分:0)

读取一次文件然后将其拆分会容易得多。您也不会丢失任何东西,因为无论如何读取的文件都是串行操作。从那里,只需设计一个方案就可以分割列表。在这种情况下,我根据索引按照所需输出列表的数量对所有内容进行分组,然后取出列表。如果行数少于您的要求,它将仅将每行放在单独的List中。

val lines: List[String] = br.lines
val outputListQuantity: Int = 2
val data: List[List[String]] = lines.zipWithIndex.groupBy(_._2 % outputListQuantity}.
                                        values.map(_.map(_._1)).toList

答案 1 :(得分:0)

好吧,如果您不介意将整个流读入内存,就足够简单了(假设该文件包含文本-因为您正在谈论mp.entrySet() .stream() .map(e-> e.getKey() + " " + e.getValue()) .forEach(System.out::println); s,但是对于二进制文件,它是相同的想法。 ):

Reader

但这似乎有点违背了这个目的:如果文件足够小以至于无法完全加载到内存中,为什么还要开始拆分呢? 因此,更实际的解决方案需要更多的投入:

 Source.fromFile("filename")
   .mkString
   .getBytes
   .grouped(chunkSize)
   .map { chunk => new BufferedReader(new InputStreamReader(chunk)) }