Java将文件读入内存以及如何不炸毁内存

问题描述

| 我是Java的新手,我尝试对文件执行MAC计算。 现在,由于在运行时不知道文件的大小,因此我不能只将所有文件加载到内存中。因此,我编写了代码,以使其可以读入一些位(本例中为4k)。 我遇到的问题是我尝试将整个文件加载到内存中,以查看这两种方法是否产生相同的哈希值。但是它们似乎产生了不同的哈希值 这是一点一点的代码:
FileInputStream fis = new FileInputStream(\"sbs.dat\");
byte[] file = new byte[4096];
m = Mac.getInstance(\"HmacSHA1\");
int i=fis.read(file);
m.init(key);
while (i != -1)
{
    m.update(file);
    i=fis.read(file);
}
mac = m.doFinal();
这是一次全部使用的方法:
File f = new File(\"sbs.dat\");
long size = f.length();
byte[] file = new byte[(int) size];
fis.read(file);
m = Mac.getInstance(\"HmacSHA1\");
m.init(key);
m.update(file);
mac = m.doFinal();
他们不应该产生相同的哈希吗? 但是,这个问题更为笼统。第一个代码是将文件加载到内存中并在while周期内执行我们想要执行的操作的正确方法吗? (套接字发送,加密文件等)。 这个问题很有用,因为我看过的每个教程都一次加载了所有内容... 更新:工作中:-D。这种方法是否可以正常通过套接字发送文件?     

解决方法

不。您不能保证在
fis.read(file)
中将读取
file.length
个字节。这就是为什么
read()
返回一个int告诉您它实际读取了多少字节的原因。 您应该改为:
m.init(key);
int i=fis.read(file);

while (i != -1)
{
    m.update(file,i);
    i=fis.read(file);
}
利用Mac.update(byte [] data,int offset,int len)方法,该方法允许您在byte []数组中指定实际数据的长度。     ,
read
函数不一定会填满整个数组。因此,您需要检查
read
函数返回的字节数,并且仅使用缓冲区的那个字节。     ,就像Jason LeBrun所说的那样-read方法并不总是读取指定数量的字节。例如:如果文件不包含4096字节的倍数,您会怎么办? 我会去这样的事情:
        FileInputStream fis = new FileInputStream(filename);
        byte[] buffer = new byte[buffersize];
        Mac m = Mac.getInstance(\"HmacSHA1\");
        m.init(key);

        int n;
        while ((n = fis.read(buffer)) != -1)
        {
            m.update(buffer,n);
        }
        byte[] mac = m.doFinal();
    

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...