Лучший способ использовать RandomAccessFile - Java - PullRequest
0 голосов
/ 06 сентября 2018

Я создаю утилиту, которая записывает блоб таблицы MSSQL в файл диска данных, используя RandomAccessFile. Это слишком медленно, потому что нам нужно всегда искать последнюю позицию и записывать содержимое потока. Пожалуйста, дайте мне знать любую другую альтернативу для ускорения записи в randomaccessfile.

У меня более 50 миллионов записей, с текущей логикой это заняло около 10 часов.

мой блок кода выглядит примерно так:

RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
InputStream inputStream = null;

while (rows.hasNext()) {
    Row row = rows.next();
    inputStream = (InputStream) row.getValues()[0];
    offset = randomAccessFile.length();
    byte[] buffer = new byte[8196];
    int count;
    randomAccessFile.seek(offset);
    randomAccessFile.setLength(offset);
    while ((count = inputStream.read(buffer)) != -1) {
        randomAccessFile.write(buffer, 0, count);
    }
}
randomAccessFile.close();   

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

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

Таким образом, используйте

BufferedWriter writer = Files.newBufferedWriter(file.toPath(), StandardOpenOptions.CREATE, StandardOpenOptions.APPEND);

вместо.

Обновление после комментария Питера: для выходного потока все в основном то же самое, только то, что Files не имеет удобной вспомогательной функции для "буферизованной" части. Therfore:

OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(file.toPath(), StandardOpenOption.CREATE, StandardOpenOption.APPEND));
0 голосов
/ 06 сентября 2018

В настоящее время вы записываете примерно 8 Кбайт (8196/1024) данных в каждой итерации, и каждая итерация выполняет операцию ввода-вывода, которая блокируется и требует времени. Попробуйте увеличить это хотя бы примерно до 1 Мб (10 000 000).

byte[] buffer = new byte[10000000];
...