читать файл побайтно, затем выполнять некоторые операции каждые n байтов - PullRequest
0 голосов
/ 28 мая 2010

Я хотел бы знать, как я могу прочитать файл побайтно, а затем выполнить некоторую операцию через каждые n байтов.

например:

Скажем, у меня есть файл size = 50 bytes, я хочу разделить его на блоки, каждый из которых n bytes. Затем каждый блок отправляется функции для выполнения некоторых операций над этими байтами. Блоки должны быть созданы во время процесса чтения и отправлены в функцию, когда блок достигает n байтов, чтобы я не использовал много памяти для хранения всех блоков.

Я хочу, чтобы вывод функции был записан / добавлен в новый файл.

Это то, чего я достиг, чтобы прочитать, но я не знаю, что это правильно:

fc = new JFileChooser();
File f = fc.getSelectedFile();
FileInputStream in = new FileInputStream(f);
byte[] b = new byte[16];
in.read(b);

Я еще ничего не сделал для процесса записи.

Ответы [ 5 ]

4 голосов
/ 28 мая 2010

Вы на правильных линиях. Попробуйте обернуть FileInputStream BufferedInputStream, что повысит эффективность ввода-вывода, читая файл по частям.

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

2 голосов
/ 28 мая 2010

Я верю, что это будет работать:

final int blockSize = // some calculation
byte[] block = new byte[blockSize];
InputStream is = new FileInputStream(f);
try {
    int ret = -1;
    do {
        int bytesRead = 0;
        while (bytesRead < blockSize) {
            ret = is.read(block, bytesRead, blockSize - bytesRead);
            if (ret < 0)
                break; // no more data
            bytesRead += ret;
        }

        myFunction(block, bytesRead);
    } while (0 <= ret);
}
finally {
    is.close();
}

Этот код будет вызывать myFunction с blockSize байтами для всех, кроме, возможно, последнего вызова.

2 голосов
/ 28 мая 2010

Пока ваш код выглядит нормально. Для чтения двоичных файлов (в отличие от текстовых файлов) вы действительно должны использовать FileInputStream (для чтения текстовых файлов вы должны использовать Reader, например FileReader).

Обратите внимание, что вы должны проверить возвращаемое значение из in.read(b);, поскольку оно может прочитать менее 16 байтов, если в конце файла осталось менее 16 байтов.

Конечно, вы должны добавить в программу цикл, который будет считывать блоки байтов, пока не дойдете до конца файла.

Чтобы записать данные в двоичный файл, используйте FileOutputStream. Этот класс имеет конструктор, который вы можете передать флаг, чтобы указать, что вы хотите добавить в существующий файл:

FileOutputStream out = new FileOutputStream("output.bin", true);

Кроме того, не забудьте позвонить close() на номера FileInputStream и FileOutputStream, когда вы закончите.

См. документацию по Java API , особенно классы в пакете java.io.

1 голос
/ 28 мая 2010

Это начало.

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

Очевидно, вам нужно читать () в цикле ...

Возможно, будет хорошей идеей повторно использовать массив, но для этого необходимо, чтобы часть, считывающая массив, копировала все, что ему нужно, а не просто сохраняла ссылку на массив.

0 голосов
/ 28 мая 2010

Я думаю, это то, что вам нужно

void readFile(String path, int n) {
    try {
        File f = new File(path);
        FileInputStream fis = new FileInputStream(f);
        int ret = 0;
        byte[] array = new byte[n];
        while(ret > -1) {
            ret = fis.read(array);
            doSomething(array, ret);
        }
                    fis.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
...