Scala文件散列

时间:2017-01-13 20:01:48

标签: scala hash nio

我已将以下程序编写为使用MD5哈希重复删除文件的快速实验

import java.nio.file.{Files, Paths}
import java.security.MessageDigest

object Test {

  def main(args: Array[String]) = {

    val startTime = System.currentTimeMillis();
    val byteArray = Files.readAllBytes(Paths.get("/Users/amir/pgns/bigPGN.pgn"))
    val endTime = System.currentTimeMillis();
    println("Read file into byte " +byteArray+ " in " + (endTime - startTime) +" ms");

    val startTimeHash = System.currentTimeMillis();
    val hash = MessageDigest.getInstance("MD5").digest(byteArray)
    val endTimeHash = System.currentTimeMillis();
    System.out.println("hashed file into " +hash+ " in " +(endTime - startTime)+ " ms");
  }
}

我注意到当我的pgn文件大约是1.5 GB的文本数据时,读取文件需要大约2.5秒,而散列它需要2.5秒。

我的问题是,如果我有大量文件,有没有更快的方法呢?

1 个答案:

答案 0 :(得分:3)

是的:不要将所有文件都读入内存!理论上这应该是更快的,虽然我没有任何巨大的文件来测试这个

import java.security.{MessageDigest, DigestInputStream}
import java.io.{File, FileInputStream}

// Compute a hash of a file
// The output of this function should match the output of running "md5 -q <file>"
def computeHash(path: String): String = {
  val buffer = new Array[Byte](8192)
  val md5 = MessageDigest.getInstance("MD5")

  val dis = new DigestInputStream(new FileInputStream(new File(path)), md5)
  try { while (dis.read(buffer) != -1) { } } finally { dis.close() }

  md5.digest.map("%02x".format(_)).mkString
}

如果一切都按照我的想法行事,这可以避免保留内存中的所有字节 - 因为它读取块,它会直接将它们消耗到散列中。请注意,您可以增加缓冲区大小以使事情变得更快......