Java Android:计算散列的更快方法

Java Android:计算散列的更快方法,java,android,hash,Java,Android,Hash,此代码将计算URI的哈希: protected void ShowHash(android.net.Uri uri) { MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); BufferedInputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri));

此代码将计算URI的哈希:

protected void ShowHash(android.net.Uri uri) {
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("MD5");
        BufferedInputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri));
        DigestInputStream dis = new DigestInputStream(is, md);
        while(dis.read() != -1) ;
        Toast.makeText(getApplicationContext(), bytesToHex(md.digest()),
                Toast.LENGTH_LONG).show();
    } catch(Exception e) {
        Toast.makeText(getApplicationContext(), e.toString(),
                Toast.LENGTH_LONG).show();
    }
    return;
}

但是对于一个大小合适的文件(比如说一张2MB的图片),这个文件会挂起大约10秒,这是一个荒谬的时间量。显然,有一种比while(dis.read()!=-1)更好的方法来处理整个文件;我应该怎么做呢?

更好的方法是以较大的块读取文件。这避免了为每个字节调用许多函数的开销。当然,您不想将整个文件读入内存,因此您可以使用一个小的缓冲区:

protected void ShowHash(android.net.Uri uri) {
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("MD5");
        BufferedInputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri));
        DigestInputStream dis = new DigestInputStream(is, md);
        byte[] buffer = new byte[1024];
        while(dis.read(buffer, 0, buffer.length) != -1) ;
        Toast.makeText(getApplicationContext(), bytesToHex(md.digest()),
                Toast.LENGTH_LONG).show();
    } catch(Exception e) {
        Toast.makeText(getApplicationContext(), e.toString(),
                Toast.LENGTH_LONG).show();
    }
    return;
}

此函数立即返回,而原始函数大约需要10秒。

我不确定是否可以更快地完成,因为我很少接触散列,但只是一个提示:我认为最好将其设置为
AsyncTask
Thread
,以防锁定UI。也许可以尝试另一个版本的
read()
读入数组,int,int)当然可以,但您仍在等待大约10秒:)如果我不想要内容(假设这是一个3GB的文件),我如何避免用不必要的副本阻塞内存?那么,也许可以分块读取文件?分配一个一定大小的数组并调用
read()
您需要多少次才能看完整个文件?