В настоящее время я разрабатываю приложение для трехмерной графики с использованием JOGL (привязка Java OpenGL). Короче говоря, у меня есть огромный двоичный файл ландшафта. Из-за его размера мне приходится транслировать фрагменты ландшафта во время выполнения. Таким образом, мы явно видим проблему произвольного доступа. Я уже закончил первую (и грязную :)) реализацию (возможно, многопоточную), где я использую глупый подход ... Вот его инициализация:
dataInputStream = new DataInputStream(new BufferedInputStream(fileInputStream,4 * 1024);
dataInputStream.mark(dataInputStream.available());
И когда мне нужно прочитать ( stream) специальный фрагмент (я уже знаю его "смещение" в файле) I ' Итак, до сих пор я прочитал 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. Я запускал этот тест в следующих условиях:
Результаты были ошеломляющими:
~ 28 секунд для RAF! ~ 0,2 секунды для FBM!
Однако его реализация RAF в этом тесте не имеет самобуферизации (о ней рассказывается в третьей статье), поэтому я предполагаю, что это вызов метода "RandomAccessFile.seek" , который так сильно снижает производительность.
Хорошо, теперь после всего того, что я узнал, остается 1 вопрос и 1 дилемма :)
Вопрос : Когда мы отображаем файл с помощью FileChannel.map копирует ли Java все содержимое файла в MappedByteBuffer? Или просто имитирует? Если он копирует, то использование подхода FBM не подходит для моей ситуации, не так ли?
Дилемма : Зависит от ваших ответов на вопрос ...
Если отображение копирует файл, то похоже, что я осталось только 2 возможных решения: RAF + самобуферизация (из 3-й статьи) или используют позицию в FileChannel (не с отображением) ... Что будет лучше?
Если отображение не копирует файл, тогда у меня есть 3 варианта: два предыдущих и сам FBM .
Edit : Еще один вопрос. Некоторые из вас говорят, что отображение не копирует файл в MappedByteBuffer. Хорошо, тогда почему я не могу сопоставить файл размером 1 ГБ, я получаю сообщение «не удалось сопоставить» ...
PS Я хотел бы получить завершенный ответ с советами, так как я не могу чтобы найти согласованную информацию по этой теме в Интернете.
Спасибо :)