Frage

This code will compute the hash of a 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;
}

But for a decent sized file (say, a 2MB picture), this will hang for about 10 seconds, which is a ridiculous amount of time. There is obviously a better way to process the whole file than while(dis.read() != -1) ;; how should I go about it?

War es hilfreich?

Lösung

A better way is to read the file in larger chunks. This avoids the overhead of many function calls for each byte. Of course, you don't want to read the entire file into memory, so you can just use a small buffer:

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;
}

This function returns instantly where the original function takes around 10 seconds.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top