В настоящее время я занимаюсь разработкой приложения для трехмерной графики с использованием JOGL (привязка Java OpenGL).Вкратце, у меня есть огромный двоичный файл ландшафта.Из-за его размера, я должен передавать потоки ландшафта во время выполнения.Поэтому мы явно видим проблему произвольного доступа.Я уже закончил первую (и грязную :)) реализацию (возможно, многопоточную), где я использую глупый подход ... Вот его инициализация:
dataInputStream = new DataInputStream(new BufferedInputStream(fileInputStream,4 * 1024);
dataInputStream.mark(dataInputStream.available());
Икогда мне нужно прочитать (поток) специальный кусок (я уже знаю его «смещение» в файле), я выполняю следующее (позор мне:)):
dataInputStream.reset();
dataInputStream.skipBytes(offset);
dataInputStream.read(whatever I need...);
Поскольку у меня мало опытаэто было первое, о чем я мог подумать :) Итак, до сих пор я прочитал 3 полезные и довольно интересные статьи (я предлагаю вам прочитать их, возможно, если вы заинтересованы в этой теме)
Байт-буферы и память без кучи - Мистер Грегори кажется грамотным в Java NIO.
Совет по Java: как быстро читать файлы [http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly] - это интересный тест.
Статьи: Настройка производительности ввода-вывода Java [http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/] - Простые рекомендации Sun, но, пожалуйста, прокрутите вниз и посмотрите там раздел «Произвольный доступ»;они показывают простую реализацию RandomAccessFile (RAF) с улучшением само-буферизации.
Mr.Грегори предоставляет несколько * .java файлов в конце своей статьи.Одним из них является сравнительный анализ между FileChannel + ByteBuffer + Mapping (FBM) и RAF.Он говорит, что он заметил 4-кратное ускорение при использовании FBM по сравнению с RAF.Я провел этот тест в следующих условиях:
- Смещение (например, место доступа) генерируется случайным образом (в области видимости файла, например, 0 - file.length ());
- Размер файла составляет 220 МБ;
- 1 000 000 доступов (75% чтения и 25% записи)
Результаты были ошеломляющими:
~ 28 сек дляRAF! ~ 0,2 сек для FBM!
Однако его реализация RAF в этом тесте не имеет собственной буферизации (3-я статья рассказывает об одном), поэтому я думаю, что это "Вызов метода RandomAccessFile.seek ", который так сильно снижает производительность.
Хорошо, теперь после всего, что я узнал, есть 1 вопрос и 1 дилемма:)
Вопрос : Когда мы отображаем файл с помощью «FileChannel.map», копирует ли Java все содержимое файла в MappedByteBuffer?Или это просто подражать?Если он копирует, то использование подхода FBM не подходит для моей ситуации, не так ли?
Дилемма : Зависит от ваших ответов на вопрос ...
Если отображение копирует файл, то кажется, что у меня есть только 2 возможных решения: RAF + самобуферизация (из 3-й статьи) или с использованием позициив FileChannel (не с отображением) ... Какой из них будет лучше?
Если отображение не копирует файл, тогда у меня есть 3 варианта: два предыдущих и Сам FBM .
Редактировать : Вот еще один вопрос.Некоторые из вас говорят, что отображение не копирует файл в MappedByteBuffer.Хорошо, тогда почему я не могу отобразить файл 1 ГБ, я получаю сообщение «не удалось сопоставить» ...
PS Я хотел бы получить полный ответ с советами,так как я не могу найти в интернете непротиворечивую информацию по этой теме.
Спасибо:)