Изменить: то, что вы хотите, это FileInputStream.getChannel (). Map (), затем адаптировать его к InputStream, а затем подключить его к DataInputStream.

тоящее время я разрабатываю приложение для 3D-графики, используя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) с улучшением само-буферизации.

Г-н Грегори предоставляет несколько файлов * .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 ГБ, я получаю сообщение "не удалось сопоставить" ...

П.С. Я хотел бы получить исчерпывающий ответ с советами, так как я не могу найти последовательную информацию по этой теме в Интернете.

Спасибо :)

Ответы на вопрос(3)

Ваш ответ на вопрос