欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Java/Android 大文件获取SHA1防止内存溢出

程序员文章站 2022-12-29 09:53:44
在java或者android开发中难免要遇到校验文件正确性的问题。比如下载一个apk包或者下载一个游戏包,担心文件会被篡改。这个时候就可以对比源文件的sha1和下载到本地的文件的sha1。 在这个过...

java或者android开发中难免要遇到校验文件正确性的问题。比如下载一个apk包或者下载一个游戏包,担心文件会被篡改。这个时候就可以对比源文件的sha1和下载到本地的文件的sha1。

在这个过程中往往会遇到文件比较大,读取很慢或者一次性读取造成内存溢出的问题。我们下面结合代码来讲解和解决这个问题。

/**

* 大文件获取 sha1 防止内存溢出

* @param file

* @return

*/

public static string getsha1value(file file){

stringbuilder builder = new stringbuilder();

fileinputstream fileinputstream = null;

try {

fileinputstream = new fileinputstream(file);

messagedigest messagedigest = messagedigest.getinstance("sha-1");

mappedbytebuffer mappedbytebuffer = null;

long buffersize = 1024*1024*2;//每2m 读取一次,防止内存溢出

long filelength = file.length();//文件大小

long lastbuffer = filelength%buffersize;//文件最后不足2m 的部分

long buffercount = filelength/buffersize;//

for(int b = 0; b < buffercount; b++){//分块映射

mappedbytebuffer = fileinputstream.getchannel().map(filechannel.mapmode.read_only, b*buffersize, buffersize);//使用内存映射而不是直接用io读取文件,加快读取速度

messagedigest.update(mappedbytebuffer);

}

if(lastbuffer != 0){

mappedbytebuffer = fileinputstream.getchannel().map(filechannel.mapmode.read_only, buffercount*buffersize, lastbuffer);

messagedigest.update(mappedbytebuffer);

}

byte[] digest =messagedigest.digest();

string hexstring = "";

for(int i =0; i < digest.length; i ++){

hexstring = integer.tohexstring(digest[i]&0xff);//转16进制数,再转成哈希码

if(hexstring.length()<2){

builder.append(0);

}

builder.append(hexstring);

}

} catch (filenotfoundexception e) {

e.printstacktrace();

} catch (nosuchalgorithmexception e) {

e.printstacktrace();

} catch (ioexception e) {

e.printstacktrace();

}finally{

try {

fileinputstream.close();

} catch (exception e2) {

e2.printstacktrace();

}

}

return builder.tostring();

}

这样,就可以快速的读取大文件,而且不会造成内存溢出。