Java чтение файла в память и как не взорвать память - PullRequest
5 голосов
/ 15 апреля 2011

Я новичок в Java и пытаюсь вычислить MAC для файла.Теперь, поскольку размер файла неизвестен во время выполнения, я не могу просто загрузить весь файл в память.Поэтому я написал код, чтобы он читался в битах (в данном случае 4 КБ).У меня проблема в том, что я пытался загрузить весь файл в память, чтобы увидеть, выдают ли оба метода один и тот же хеш.Однако они, кажется, производят разные хэшиони оба производят один и тот же хеш?

Однако вопрос более общий.Является ли первый код правильным способом загрузки файла в память на куски и выполнения всего, что мы хотим сделать в цикле while?(отправка сокета, шифрование файла и т. д.).Этот вопрос полезен, потому что каждый урок, который я видел, загружает все сразу ...

Обновление: Работает :-D.Будет ли этот подход работать правильно, отправляя файл по частям через сокет?

Ответы [ 3 ]

5 голосов
/ 15 апреля 2011

Нет. У вас нет гарантии, что в fis.read(file) будет прочитано file.length байт. Вот почему read() возвращает целое число, чтобы сказать вам, сколько байтов он фактически прочитал.

Вы должны вместо этого сделать это:

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 [].

4 голосов
/ 15 апреля 2011

Функция read не обязательно заполнит весь ваш массив. Итак, вам нужно проверить, сколько байтов было возвращено функцией read, и использовать только столько байтов вашего буфера.

1 голос
/ 16 апреля 2011

Точно так же, как говорит Джейсон Лебрун, - метод чтения не всегда читает указанное количество байтов.Например: что, по вашему мнению, произойдет, если файл не будет кратен 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...