在java / scala

时间:2018-04-02 05:57:32

标签: java scala file-io java-io

我在Scala中阅读7z和zip文件。我这样做的方法是通过读取文件中的字节如下

val zipInputStream = new ZipInputStream(new FileInputStream(file));
var arrayBufferValues = ArrayBuffer[String]();
val buffer = new Array[Byte](1024);
var readData:Int = 0;
while({entry = zipInputStream.getNextEntry; entry != null}) {
       while({readData = archiveFile.read(buffer); readData != -1}) {
             content7zStream.write(buffer, 0, readData);
             //println(contentBytes.toString());
             arrayBufferValues += content7zStream.toString("UTF-8");
             println(arrayBufferValues.mkString)
       }
       println("Done with processing file ====>>>>> " + Paths.get(file).getFileName + " ---- " + entry.getName);
       parseFilesMap.put(Paths.get(file).getFileName + "^" + entry.getName, arrayBufferValues)
       arrayBufferValues.clear();
       content7zStream.close(); 
}

但是,当7z文件中有多个csv文件(比如大约20 MB)时,我发现很多性能问题。

处理需要数小时,而且该过程似乎仍未完成。有时我会收到OutOfMemory异常。

有更好的方法可以做到这一点,还是我错过了什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

以下是一些观察结果,希望有所帮助:

  // definitely a performance killer
  // try loging something shorter or comment it ouf if not really needed
  println(arrayBufferValues.mkString)

20 MB的压缩文件可以是相对大量的数据,然后放入内存,即arrayBufferValues

我刚创建了一些小例子(不要在任何生产代码中执行此操作):

  var arrayBufferValues = ArrayBuffer[String]()

  val start = System.currentTimeMillis()

  while (true) {
    try {
      arrayBufferValues += Random.nextString(1024)
    }
    catch {
      case e: OutOfMemoryError ⇒
        println(s"${System.currentTimeMillis() - start}ms")
        System.exit(0)
    }
  }

在我的本地和特定设置上使用此方法,我需要在160秒内导致OutOfMemory。我的假设是你的进程会获取一些非常大的文件,所以你可以给它额外的内存,这样就可以完成处理。

我用提供的例子玩了一下。

然后我使用以下答案调整了运行时:https://stackoverflow.com/a/2294280/7413631

以下是一些测试结果(在我的本地机器上):

-Xmx200m  => 11090ms
-Xmx300m  => 15295ms
-Xmx1024m => 54221ms
....

基本上合乎逻辑的是,为进程提供的内存越多,用完它就需要的时间就越多。哪种听起来像你的症状。

如果您想继续按照现在的方式处理,我的建议是为您的流程提供更多内存。

并且不要打印那么多而mkString不需要的地方,它会杀死你的表现。