Потоковая передача файлов в Java

В настоящее время я разрабатываю приложение для трехмерной графики с использованием JOGL (привязка Java OpenGL). Короче говоря, у меня есть огромный двоичный файл ландшафта. Из-за его размера мне приходится транслировать фрагменты ландшафта во время выполнения. Таким образом, мы явно видим проблему произвольного доступа. Я уже закончил первую (и грязную :)) реализацию (возможно, многопоточную), где я использую глупый подход ... Вот его инициализация:

dataInputStream = new DataInputStream(new BufferedInputStream(fileInputStream,4 * 1024);
dataInputStream.mark(dataInputStream.available());

И когда мне нужно прочитать ( stream) специальный фрагмент (я уже знаю его "смещение" в файле) I ' Итак, до сих пор я прочитал 3 полезных и довольно интересных статьи (предлагаю вам прочитать их, возможно, если вам интересна эта тема)

  1. Байтовые буферы и память без кучи - кажется, мистер Грегори чтобы быть грамотным в Java NIO.

  2. Совет по Java: Как быстро читать файлы [http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly] - Это интересный тест.

  3. Статьи: Настройка Производительность ввода-вывода Java [http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/] - простые рекомендации Sun, но, пожалуйста, прокрутите вниз и посмотрите там раздел «Произвольный доступ»; они показывают простую реализацию RandomAccessFile (RAF) с улучшенной самобуферизацией.

Mr. Грегори приводит несколько файлов * .java в конце своей статьи. Один из них - это сравнительный анализ между FileChannel + ByteBuffer + Mapping (FBM) и RAF. Он говорит, что заметил 4-кратное ускорение при использовании FBM по сравнению с RAF. Я запускал этот тест в следующих условиях:

  1. Смещение (например, место доступа) генерируется случайным образом (в области видимости файла, например, 0 - file.length ());
  2. Размер файла составляет 220 МБ;
  3. 1 000 000 обращений (75% чтения и 25% записи)

Результаты были ошеломляющими:

~ 28 секунд для RAF! ~ 0,2 секунды для FBM!

Однако его реализация RAF в этом тесте не имеет самобуферизации (о ней рассказывается в третьей статье), поэтому я предполагаю, что это вызов метода "RandomAccessFile.seek" , который так сильно снижает производительность.

Хорошо, теперь после всего того, что я узнал, остается 1 вопрос и 1 дилемма :)

Вопрос : Когда мы отображаем файл с помощью FileChannel.map копирует ли Java все содержимое файла в MappedByteBuffer? Или просто имитирует? Если он копирует, то использование подхода FBM не подходит для моей ситуации, не так ли?

Дилемма : Зависит от ваших ответов на вопрос ...

  1. Если отображение копирует файл, то похоже, что я осталось только 2 возможных решения: RAF + самобуферизация (из 3-й статьи) или используют позицию в FileChannel (не с отображением) ... Что будет лучше?

  2. Если отображение не копирует файл, тогда у меня есть 3 варианта: два предыдущих и сам FBM .

Edit : Еще один вопрос. Некоторые из вас говорят, что отображение не копирует файл в MappedByteBuffer. Хорошо, тогда почему я не могу сопоставить файл размером 1 ГБ, я получаю сообщение «не удалось сопоставить» ...

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

Спасибо :)

8
задан Wim Coenen 24 March 2011 в 18:54
поделиться