首页 > 解决方案 > 在scala中将文件分块成多个流

问题描述

我的程序中有一个用例,我需要获取一个文件,将它们平均拆分 N 次并远程上传。

我想要一个函数,比如 aFile并输出BufferedReader. 我可以将它们分发到其中并将它们发送到另一个使用某些 API 来存储它们的函数。

我见过作者使用.lines()a 方法的例子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)
}

我想上面的例子是有效的,它并不漂亮,但它有效。

我的问题:

标签: scalafilebufferedreader

解决方案


好吧,如果您不介意将整个流读入内存,这很容易(假设该文件包含文本 - 因为您在谈论Readers,但它与二进制文件的想法相同):

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

但这似乎有点违背了目的:如果文件小到可以完全加载到内存中,为什么还要一开始就拆分它呢?因此,更实际的解决方案涉及更多:

  def splitFile(
    input: InputStream, 
    chunkSize: Int
  ): Iterator[InputStream] = new AbstractIterator[InputStream] {
     var hasNext = true
     def next = {
       val buffer = new Array[Byte](chunkSize)
       val bytes = input.read(buffer)
       hasNext = bytes == chunkSize
       new ByteArrayInputStream(buffer, 0, bytes max 0)
     }
  }

推荐阅读