Как записать файл без выделения всего байтового массива в память? - PullRequest
1 голос
/ 13 августа 2010

Это вопрос новичка, я знаю.Можете ли вы, ребята, помочь?

Я говорю о больших файлах, конечно, более 100 МБ.Я представляю какую-то петлю, но я не знаю, что использовать.Chunked stream?

Одно точно: я не хочу что-то вроде этого (псевдокод):

File file = new File(existing_file_path);
byte[] theWholeFile = new byte[file.length()]; //this allocates the whole thing into memory

File out = new File(new_file_path);
out.write(theWholeFile);

Чтобы быть более конкретным, я должен переписать апплет, которыйзагружает файл в кодировке base64 и декодирует его в «обычный» файл.Поскольку он сделан с байтовыми массивами, он содержит в два раза больший размер файла в памяти: один кодируется в base64, а другой - в декодированном.Мой вопрос не о base64.Речь идет об экономии памяти.

Можете ли вы указать мне правильное направление?Спасибо!

Ответы [ 5 ]

4 голосов
/ 13 августа 2010

Из вопроса выясняется, что вы читаете содержимое файла в кодировке base64 в массив, декодируете его в другой массив, прежде чем окончательно сохраните его.

Это немного накладные расходы при рассмотрении памяти,Особенно учитывая тот факт, что используется кодировка Base64.Это может быть сделано несколько более эффективным путем:

  • Чтение содержимого файла с использованием FileInputStream , предпочтительно украшенного BufferedInputStream .
  • Расшифровка на лету.Символы в кодировке Base64 могут быть прочитаны группами по 4 символа для декодирования на лету.
  • Запись вывода в файл с использованием FileOutputStream , опять же предпочтительно с расширением BufferedOutputStream .Эта операция записи также может выполняться после каждой отдельной операции декодирования.

Буферизация операций чтения и записи выполняется для предотвращения частого доступа к вводу-выводу.Вы можете использовать размер буфера, соответствующий загрузке вашего приложения;обычно размер буфера выбирается равным с некоторой степенью двойки, поскольку такое число не имеет «несоответствия импеданса» с буфером физического диска .

2 голосов
/ 13 августа 2010

Возможно FileInputStream в файле, считывание фрагментов фиксированной длины, выполнение преобразования и запись их в FileOutputStream ?

0 голосов
/ 22 декабря 2017

Вы можете использовать org.apache.commons.io.FileUtils. Этот класс утилит предоставляет и другие опции, помимо того, что вы ищете. Например:

  • FileUtils.copyFile(final File srcFile, final File destFile)
  • FileUtils.copyFile(final File input, final OutputStream output)
  • FileUtils.copyFileToDirectory(final File srcFile, final File destDir)

И так далее. Также вы можете следовать этой пачке.

0 голосов
/ 13 августа 2010

Используйте этот base64 кодер / декодер , который обернет ваш поток ввода файлов и обработает декодирование на лету:

InputStream input = new Base64.InputStream(new FileInputStream("in.txt"));
OutputStream output = new FileOutputStream("out.txt");

try {
    byte[] buffer = new byte[1024];
    int readOffset = 0;
    while(input.available() > 0) {
        int bytesRead = input.read(buffer, readOffset, buffer.length);
        readOffset += bytesRead;
        output.write(buffer, 0, bytesRead);
    }
} finally {
    input.close();
    output.close();
}
0 голосов
/ 13 августа 2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...