Несколько объектов Java, читающих разные части одного и того же файла

Я работаю над проектом, в котором у меня будет двоичный файл. Файл разбит на несколько разделов, каждый из которых представляет собой список значений-примитивов. Мне нужно решение, в котором я могу иметь набор объектов, каждый из которых представляет раздел файла. Затем все эти коллекции хранятся в объекте «файл», который представляет файл в целом.

Каждый объект коллекций должен будет обеспечивать последовательный доступ к каждому значению в представленном разделе файла. Какой метод обеспечит наиболее быстрое извлечение данных без предварительной загрузки всех данных в память?

Также было бы неплохо, если бы две отдельные коллекции одного и того же объекта «файл» могли быть доступны для двух отдельных потоков, но это не так важно.


person Troy Stopera    schedule 05.06.2015    source источник
comment
Зависит от того, какая кодировка у вас установлена ​​по умолчанию в вашей системе... Пожалуйста, предоставьте и это...   -  person CoderNeji    schedule 05.06.2015
comment
@CoderNeji Он сказал, что это двоичный файл.   -  person Kayaman    schedule 05.06.2015
comment
Насколько большой довольно большой? Вы вполне можете обнаружить, что стремление к эффективности стоит вам огромных усилий в коде и обслуживании, которые в конечном итоге не стоят того.   -  person Jon Skeet    schedule 05.06.2015
comment
Это просто файл, который начинается с таблицы, содержащей индекс каждого раздела. Затем каждый раздел содержит числовые значения (shorts или ints) в зависимости от файла.   -  person Troy Stopera    schedule 05.06.2015
comment
Таким образом, вы, по сути, пытаетесь создать своего рода виртуальную память (поскольку вы не хотите читать все данные в памяти). FileChannel и RandomAccessFile подойдут, InputStream не очень. Также отметьте, чтобы закрыть вопрос.   -  person Kayaman    schedule 05.06.2015
comment
@Kayaman, что не так с этим вопросом? Я ищу разные идеи и реализации.   -  person Troy Stopera    schedule 05.06.2015
comment
Является ли файл структурированным двоичным файлом... Например, с заголовками и всем остальным... если да, обратитесь к этому.... stackoverflow.com/questions/277944/   -  person CoderNeji    schedule 05.06.2015
comment
@TroyStopera SO предпочитает простые, хорошо структурированные вопросы, на которые есть окончательные ответы (отсюда и близкий тип, основанный на мнении). Мозговой штурм и обмен идеями здесь не подходят.   -  person Kayaman    schedule 05.06.2015
comment
@CoderNeji Моя проблема не в том, как читать файлы, а в том, как иметь несколько объектов, каждый из которых представляет раздел файла.   -  person Troy Stopera    schedule 05.06.2015
comment
Благодаря этому вы можете получить доступ к любому большому файлу... codeproject.com/Questions/543821/... Позвольте мне посмотреть, чего вы хотите.. Подождите...   -  person CoderNeji    schedule 05.06.2015
comment
@Kayaman Думаю, я просто не понимаю правил. Я чувствую, что мой вопрос представляет собой практическую проблему, на которую можно ответить и которая уникальна для разработки программного обеспечения. Позвольте мне улучшить мой вопрос...   -  person Troy Stopera    schedule 05.06.2015
comment
Вы можете сделать это... Сначала прочитайте файл целиком... Затем разделите его по размеру, а затем назначьте объект для каждого разделения... Это единственный способ сделать это   -  person CoderNeji    schedule 05.06.2015
comment
@CoderNeji Почему это единственный способ? Я мог бы сохранить указатель на точку в файле в каждом объекте коллекции, а затем использовать его для доступа к данным. Я перефразировал свой вопрос, он может предоставить более подробную информацию.   -  person Troy Stopera    schedule 05.06.2015
comment
@TroyStopera Большинство вопросов в формате «Что лучше ... Должен ли я делать то или это и т. Д.» Закрыты. У вас было 3 возможных решения (хотя я не мог понять, что Inputstream существует), поэтому ваш вопрос был в основном о том, можете ли вы решить за меня, а вопрос о потоках — это совершенно отдельная проблема. Однако, чтобы больше не затягивать это, FileChannel был бы самым современным и быстрым способом (поскольку он может мгновенно отображать части памяти).   -  person Kayaman    schedule 05.06.2015
comment
@Kayaman Я никоим образом не просил людей решать, и если это так, я извиняюсь. Я перечислил их, потому что сам думал об этом, но теперь я знаю, что должен держать свои предыдущие возможные решения при себе, когда запрашиваю помощь у сообщества. Часть Threading не была вопросом, это было еще одно требование. И InputStream был там, потому что вы можете прочитать файл с InputStream. Еще раз извините за плохой вопрос, и спасибо за вашу помощь.   -  person Troy Stopera    schedule 05.06.2015
comment
Отдельный доступ к данным бинарного файла из объектов файла и раздела - два уровня. Я бы начал с ввода-вывода с отображением памяти (MappedByteBuffer от nio), который, скорее всего, хорошо подойдет для вашего варианта использования.   -  person laune    schedule 05.06.2015
comment
@Kayaman Теперь, где следует задавать такие вопросы? Я начинаю терять интерес к ТАК быстро, потому что такие вопросы, как этот, я нахожу действительно интересными, а не почему это вызывает NPE? и подобные.   -  person laune    schedule 05.06.2015
comment
@laune Спасибо! Я посмотрел MappedByteBuffer. Мне любопытно, загружает ли MappedByteBuffer все данные в память? Я бы предположил, что это так, поскольку это буфер.   -  person Troy Stopera    schedule 05.06.2015
comment
Ах! Отличный вопрос! - ОС обычно имеет функцию сопоставления файловой памяти постранично в адресное пространство процесса. Таким образом, в память считываются только те части, к которым действительно осуществляется доступ. - Я использовал это для огромных файлов, используя Java 7 или 8 в Linux, и это сработало довольно хорошо.   -  person laune    schedule 05.06.2015
comment
Хотите присоединиться ко мне в чате?   -  person Kayaman    schedule 05.06.2015
comment
@laune Спасибо! Я пытался найти окончательный ответ на вопрос, хранит ли он все это или как именно это работает. Это именно тот ответ, который я искал.   -  person Troy Stopera    schedule 05.06.2015
comment
@TroyStopera Обратите внимание, что FileChannel.map() возвращает MappedByteBuffer.   -  person Kayaman    schedule 05.06.2015
comment
@Kayaman Да, я знал это. Вот почему в моем первоначальном вопросе я сказал FileChannel/MappedByteBuffer. Я не пытаюсь сказать, что вы не ответили на мой вопрос, я говорю, что лаун ответила на него более уважительно. Это только мой 4-й или 5-й вопрос, опубликованный на SO, и нет необходимости критиковать мой вопрос, когда в целом это хороший вопрос, он просто не соответствует строгим стандартам SO. Вместо этого вы могли бы помочь мне перефразировать мой вопрос. Я не решаюсь публиковать здесь, так как у SO такая жесткая модерация.   -  person Troy Stopera    schedule 05.06.2015
comment
@TroyStopera У меня была дискуссия с Laune в чате (я надеялся, что вы тоже присоединитесь) об этом посте, постах о SO/программировании в целом, качестве постов и других подобных вещах. Я попросил Лауна завершить этот вопрос ответом, содержащим информацию в хороших комментариях, чтобы улучшить этот вопрос (много комментариев и отсутствие ответов не делает хороший вопрос), и я отозвал свой закрытый голос. Модерация может показаться жесткой, но мы стараемся поддерживать качество на должном уровне.   -  person Kayaman    schedule 05.06.2015
comment
@Kayaman Я согласен, что нужен был ответ! Я не присоединился к чату, потому что мой предыдущий опыт общения с модераторами в настройках чата всегда был негативным. Я прошу прощения. Что касается поддержания качества, я просто чувствую, что модераторы должны быстро отмечать, а не давать конструктивный отзыв, чтобы сделать вопрос качественным. Но я закончу это сейчас, так как это становится слишком мета, и я не хотел бы, чтобы меня помечали;)   -  person Troy Stopera    schedule 05.06.2015


Ответы (1)


Хороший подход состоит в том, чтобы разделить решение на уровни, здесь: один для файлового ввода-вывода, сопоставления байтов с короткими и целыми числами Java, другой для абстракции разделов файла и всего файла.

MappedByteBuffer java.nio обеспечивает хороший интерфейс между "массивом байтов" файла произвольного доступа и тем, что вам нужно для получения из него типизированных данных Java.

Как упомянул Каяман, FileChannel.map() возвращает MappedByteBuffer, и вы можете легко перемещаться по нему с помощью его методов.

Реализация должна использовать функцию ОС для отображения страниц памяти на страницы файлов, фактически обращаясь к файлу только к тому, к чему вы действительно обращаетесь в памяти. (Я недавно использовал это с Java 8 и Linux, и он хорошо работал с файлами, превышающими даже емкость одного MappedByteBuffer.)

person laune    schedule 05.06.2015
comment
Как я уже сказал выше: это будет работать очень хорошо, и это именно то, что мне нужно! Спасибо! - person Troy Stopera; 05.06.2015
comment
TroyStopera: Часть вашей благодарности принадлежит @Kayaman, который подтолкнул меня собрать все в этот ответ. Удачи! - person laune; 05.06.2015