Как мне прочитать файл без какой-либо буферизации в Java?

Я работаю над проблемами в Programming Pearls, 2-е издание, столбец 1. Одна из проблем связана с написанием программы, которая использует только около 1 мегабайта памяти для хранения содержимого файла в виде битового массива, где каждый бит представляет, является ли или в файле нет 7-значного числа. Поскольку Java — это язык, с которым я лучше всего знаком, я решил использовать его, хотя автор, похоже, имел в виду C и C++.

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

Я думал, что InputStreamReader будет хорошим решением, пока не прочитал это в Документация по Java:

Чтобы обеспечить эффективное преобразование байтов в символы, из базового потока может быть прочитано больше байтов, чем необходимо для выполнения текущей операции чтения.

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


person Drake Sobania    schedule 17.08.2014    source источник
comment
Я не очень понимаю мотивацию проблемы. Несколько килобайт для входного буфера не убьют вас, если ваша первичная структура данных составляет 1 МБ.   -  person user207421    schedule 17.08.2014


Ответы (1)


Одна из проблем связана с написанием программы, которая использует всего около 1 мегабайта памяти для хранения содержимого файла в виде битового массива, где каждый бит представляет, присутствует ли в файле 7-значное число.

Это означает, что вам нужно читать файл как байты (не символы).

Предполагая, что у вас действительно есть потребность читать из файла без буферизации, вам следует использовать класс FileInputStream. Он не выполняет буферизацию. Он читает (или пытается прочитать) именно то количество байтов, которое вы запросили.

Если вам затем нужно преобразовать эти байты в символы, вы можете сделать это, применив соответствующий конструктор String к byte или byte[]. Обратите внимание, что для многобайтовых кодировок символов, таких как UTF-8, вам необходимо прочитать достаточное количество байтов для завершения каждого символа. Сделать это без возможности упреждающего чтения немного сложно... и влечет за собой "знание* кодировки символов, которую вы читаете.

(Вы можете избежать этого знания, используя CharsetDecoder напрямую. Но тогда вам нужно будет использовать метод decode, который работает с Buffer объектами, а это тоже немного сложно.)


Что бы это ни стоило, Java проводит четкое различие между вводом-выводом потока байтов и потока символов. Первый поддерживается InputStream и OutputStream, а второй — Reader и Write. Класс InputStreamReader — это Reader, который адаптирует InputStream. Вы не должны использовать его для приложения, которое хочет читать побайтно.

person Stephen C    schedule 17.08.2014