Java/Android 大文件获取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();
}
这样,就可以快速的读取大文件,而且不会造成内存溢出。