Изменить: то, что вы хотите, это 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 ГБ, я получаю сообщение "не удалось сопоставить" ...
П.С. Я хотел бы получить исчерпывающий ответ с советами, так как я не могу найти последовательную информацию по этой теме в Интернете.
Спасибо :)