Java Scanner类是否立即将整个文件加载到内存中?

Java Scanner类是否立即将整个文件加载到内存中?,java,java.util.scanner,Java,Java.util.scanner,我经常使用Scanner类来读取文件,因为它非常方便 String inputFileName; Scanner fileScanner; inputFileName = "input.txt"; fileScanner = new Scanner (new File(inputFileName)); 我的问题是,上面的语句是否会立即将整个文件加载到内存中?或者对FileScaner执行后续调用,如 fileScanner.next

我经常使用Scanner类来读取文件,因为它非常方便

      String inputFileName;
      Scanner fileScanner;

      inputFileName = "input.txt";
      fileScanner = new Scanner (new File(inputFileName));
我的问题是,上面的语句是否会立即将整个文件加载到内存中?或者对FileScaner执行后续调用,如

      fileScanner.nextLine();

从文件中读取(即从外部存储器而不是从内存中读取)?我问这个问题是因为我担心如果文件太大而无法一次读入内存会发生什么。谢谢

您最好使用类似大型文件的工具。可以找到一个基本示例。

通过阅读代码,默认情况下每次加载1KB。对于长文本行,缓冲区的大小可能会增加。(到您拥有的最长文本行的大小)

如果您阅读了源代码,您可以自己回答问题

有关扫描仪构造函数的实现似乎显示:

public Scanner(File source) throws FileNotFoundException {
        this((ReadableByteChannel)(new FileInputStream(source).getChannel()));
}
后者将其包装到一个读卡器中:

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));
    }

因此,扫描器似乎不能一次读取整个文件。

在ACM竞赛中,快速读取非常重要。在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);
        }
    }
您可以使用
StringTokenizer
捕捉所需的任何部分

如果对大文件使用
扫描仪
,则会出现一些错误。从一个包含10000行的文件中读取100行

扫描器可以从任何实现可读性的对象读取文本 接口。如果调用底层可读的 Readable.read(java.nio.CharBuffer)方法抛出一个IOException 扫描仪假定已到达输入端。这个 基础服务器引发的最新IOException可以是 通过ioException()方法检索

在API中显示


祝你好运

+1不知道它没有立即读取整个文件。答案已编辑。但是,它仍然会遇到BufferedReader+FileReader无法解决的较大文件问题。@Aidanc什么样的问题?@Sheriff请看edalorzo的答案。看来我看错了整个文件,但是我留下了我的答案,因为Buffered+FileReader可以更好地处理大文件。@Aidanc-你为什么这么说?当然,这取决于您是否需要Scanner的解析功能。当然,如果OP只打算使用
nextLine()
,那么BufferedReader可能会快一点。(请注意,OP中说“对fileScanner的后续调用,如
fileScanner.nextLine()
”…)为什么您认为BufferedReader更好?答案是否定的。但它按缓冲区读取文件-这意味着以块为单位。
Red Alder
Ash
Aspen
Basswood
Ash
Beech
Yellow Birch
Ash
Cherry
Cottonwood