Питання Мапування файлів розміром більше 2 Гб за допомогою Java


Можна загалом сказати: як ви реалізуєте метод byte[] get(offset, length) для файлу, що відображається на карті пам'яті, що перевищує 2 Гб у Java.

З контекстом:

Я намагаюся ефективно читати файли, розмір яких перевищує 2 Гб, при випадковому вводі / виводі. Звичайно, ідея полягає в тому, щоб використовувати Java nio і API, нанесені на пам'ять.

Проблема полягає в обмеженні 2 Гб для відображення пам'яті. Одним із рішень буде карта декількох сторінок 2 Гб та індекс через зсув.

Тут є аналогічне рішення:

Бінарний пошук у відсортованому (на карті пам'яті?) Файлі в Java

Проблема з цим рішенням полягає в тому, що вона призначена для читання байтів, коли мій API має читати byte[] (так що мій API буде щось подібним read(offset, length))

Чи буде це просто працювати, щоб змінити цю максимальну get() до a get(offset, length)? Що відбувається тоді, коли byte[] я читаю лежить між двома сторінками?


10
2018-02-22 21:23


походження




Відповіді:


Ні, моя відповідь Бінарний пошук у відсортованому вигляді (з пам'яттю?) не буде працювати, щоб змінити get() до get(offset, length) з-за межі масивів, накладеної на пам'ять, як ви підозрюєте. Я бачу два можливих рішення:

  1. Перекривайте файли з пам'яттю.  Коли ви читаєте, виділіть файл зі схемою пам'яті із початковим баєм безпосередньо перед початковим байтом читання. Цей підхід не буде працювати, якщо він читає більше 50% максимального розміру карти пам'яті.
  2. Створіть метод створення масиву байтів, який буде зчитувати з двох різних двох різних файлів, пов'язаних із пам'яттю.  Я не зацікавлений в такому підході, оскільки я думаю, що деякі з прибутків продуктивності будуть втрачені, тому що результуючий масив не буде віднесено до пам'яті.

4
2018-04-06 07:18



Які втрати в продуктивності будуть втрачені? Якщо ви повертаєте а byte[], ви копіюєте з mmap()у будь-якому випадку. Дзвінок System.arraycopy двічі замість одного разу на одній і тій же загальній кількості байтів не набагато гірше. - Scott Lamb
@ Шотлам Лемб: Я погоджуюсь, що удар по роботі буде незначним для тих, хто, ймовірно, має рідкісні умови, коли get() потрібно прочитати з двох різних карт в "бінарному пошуку" algo. Моя відповідь каже, що вам потрібно кодувати його, отже, два варіанти. Просто додавши зміщення без нового коду get() призведе до жорстких помилок, таких як помилка індексу за межами. - Stu Thompson