Загружает ли класс Scanner весь файл в память сразу?

Я часто использую класс Scanner для чтения файлов, потому что это очень удобно.

      String inputFileName;
      Scanner fileScanner;

      inputFileName = "input.txt";
      fileScanner = new Scanner (new File(inputFileName));

Мой вопрос: загружает ли приведенный выше оператор весь файл в память сразу? Или выполните последующие вызовы файлового сканера, например

      fileScanner.nextLine();

читать из файла (т.е. из внешнего хранилища, а не из памяти)? Я спрашиваю, потому что меня беспокоит, что может случиться, если файл будет слишком большим, чтобы его можно было сразу прочитать в памяти. Спасибо.


person CodeBlue    schedule 26.04.2012    source источник
comment
Ответ - нет. Но он читает файл по буферу, то есть по частям.   -  person Alex    schedule 15.04.2015


Ответы (4)


Если вы читаете исходный код, вы можете сами ответить на вопрос.

Похоже, что реализация рассматриваемого конструктора сканера показывает:

public Scanner(File source) throws FileNotFoundException {
        this((ReadableByteChannel)(new FileInputStream(source).getChannel()));
}

Позже это завернуто в Reader:

private static Readable makeReadable(ReadableByteChannel source, CharsetDecoder dec) {
    return Channels.newReader(source, dec, -1);
}

И читается с использованием размера буфера

private static final int BUFFER_SIZE = 1024; // change to 1024;

Как вы можете видеть в финальном конструкторе в цепочке построения:

private Scanner(Readable source, Pattern pattern) {
        assert source != null : "source should not be null";
        assert pattern != null : "pattern should not be null";
        this.source = source;
        delimPattern = pattern;
        buf = CharBuffer.allocate(BUFFER_SIZE);
        buf.limit(0);
        matcher = delimPattern.matcher(buf);
        matcher.useTransparentBounds(true);
        matcher.useAnchoringBounds(false);
        useLocale(Locale.getDefault(Locale.Category.FORMAT));
    }

Получается, что сканер не читает сразу весь файл.

person Edwin Dalorzo    schedule 26.04.2012
comment
+1 Не знал, что он не прочитал весь файл сразу. Ответ отредактирован. Однако он по-прежнему сталкивается с проблемами с большими файлами, которых нет у BufferedReader + FileReader. - person Aidanc; 26.04.2012
comment
@Aidanc Какие проблемы? - person Edwin Dalorzo; 26.04.2012

Судя по коду, по умолчанию загружается 1 КБ за раз. Размер буфера может увеличиваться для длинных строк текста. (до размера самой длинной строки текста, которая у вас есть)

person Peter Lawrey    schedule 26.04.2012

В ACM Contest быстрое чтение очень важно. В Java мы обнаружили, что использовать что-то подобное намного быстрее...

    FileInputStream inputStream = new FileInputStream("input.txt");
    InputStreamReader streamReader = new InputStreamReader(inputStream, "UTF-8");
    BufferedReader in = new BufferedReader(streamReader);
    Map<String, Integer> map = new HashMap<String, Integer>();
    int trees = 0;
    for (String s; (s = in.readLine()) != null; trees++) {
        Integer n = map.get(s);
        if (n != null) {
            map.put(s, n + 1);
        } else {
            map.put(s, 1);
        }
    }

В этом случае файл содержит имена деревьев...

Red Alder
Ash
Aspen
Basswood
Ash
Beech
Yellow Birch
Ash
Cherry
Cottonwood

Вы можете использовать StringTokenizer для захвата любой части строки, которую хотите.

У нас есть некоторые ошибки, если мы используем Scanner для больших файлов. Прочитайте 100 строк из файла с 10000 строками!

Сканер может считывать текст с любого объекта, реализующего интерфейс Readable. Если вызов базового метода чтения Readable.read(java.nio.CharBuffer) вызывает исключение IOException, сканер предполагает, что достигнут конец ввода. Самое последнее исключение IOException, созданное базовым объектом для чтения, может быть получено с помощью метода ioException().

сообщает в API

Удачи!

person Paul Vargas    schedule 26.04.2012

Лучше использовать что-то вроде BufferedReader с помощью FileReader для большие файлы. Базовый пример можно найти здесь .

person Aidanc    schedule 26.04.2012
comment
@Sheriff Смотрите ответ edalorzo. Похоже, я ошибаюсь в чтении всего файла, однако я оставил свой ответ, потому что Buffered + FileReader лучше обрабатывает большие файлы. - person Aidanc; 26.04.2012
comment
@Aidanc - почему ты так говоришь? Конечно, это зависит от того, нужны ли вам функции анализа Scanner. Конечно, если OP только будет использовать nextLine(), BufferedReader может быть немного быстрее. (Обратите внимание, что ОП говорит о последующих вызовах файлового сканера как fileScanner.nextLine() ...) - person Stephen C; 26.04.2012
comment
Как вы думаете, почему BufferedReader лучше? - person CodeBlue; 26.04.2012