【问题标题】:Java reading file into memory and how not to blow up memoryJava将文件读入内存以及如何不炸毁内存
【发布时间】:2011-08-06 14:27:44
【问题描述】:

我是一个 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。这种方法是否可以通过套接字分段发送文件?

【问题讨论】:

    标签: java file memory


    【解决方案1】:

    没有。您无法保证在 fis.read(file) 中将读取 file.length 字节。这就是为什么read() 返回一个 int 来告诉你它实际读取了多少字节。

    你应该这样做:

    m.init(key);
    int i=fis.read(file);
    
    while (i != -1)
    {
        m.update(file, 0, i);
        i=fis.read(file);
    }
    

    利用 Mac.update(byte[] data, int offset, int len) 方法,该方法允许您在 byte[] 数组中指定实际数据的长度。

    【讨论】:

    • 多哈。我觉得自己像个白痴,我完全忘记了 Mac 类中有 3 种更新方法。尽管如此,我仍然会在一些简单的事情上浪费时间。会试一试,但听起来不错。
    【解决方案2】:

    read 函数不一定会填满整个数组。因此,您需要检查从 read 函数返回的字节数,并且只使用缓冲区的这些字节数。

    【讨论】:

      【解决方案3】:

      就像 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, 0, n);
              }
              byte[] mac = m.doFinal();
      

      【讨论】:

        猜你喜欢
        • 2014-04-07
        • 1970-01-01
        • 2010-11-08
        • 2013-09-12
        • 1970-01-01
        • 2016-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多