我经常使用Scanner类来读取文件,因为它非常方便。
String inputFileName;
Scanner fileScanner;
inputFileName = "input.txt";
fileScanner = new Scanner (new File(inputFileName));
我的问题是,上面的语句是否一次将整个文件加载到内存中?或者对fileScanner进行后续调用,如
fileScanner.nextLine();
从文件中读取(即从外部存储器而不是从内存中读取)?我问,因为我担心如果文件太大而无法一次性读入内存会发生什么。谢谢。
答案 0 :(得分:13)
如果你阅读了源代码,你可以自己回答这个问题。
似乎有问题的Scanner构造函数的实现显示:
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));
}
因此,扫描仪似乎不会立即读取整个文件。
答案 1 :(得分:1)
从阅读代码开始,默认情况下一次加载1 KB。对于长行文本,缓冲区的大小可以增加。 (达到你所拥有的最长文本行的大小)
答案 2 :(得分:0)
对于大型文件,最好使用BufferedReader和FileReader之类的内容。可以找到一个基本示例here。
答案 3 :(得分:0)
在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);
}
}
该文件包含树名...
Red Alder
Ash
Aspen
Basswood
Ash
Beech
Yellow Birch
Ash
Cherry
Cottonwood
您可以使用StringTokenizer
来捕捉您想要的任何部分。
如果我们对大文件使用Scanner
,我们会遇到一些错误。从10000行的文件中读取100行!
扫描程序可以从任何实现Readable的对象中读取文本 接口。如果调用底层可读的 Readable.read(java.nio.CharBuffer)方法然后抛出IOException 扫描仪假定已到达输入的结尾。该 最近由底层可读引发的IOException可以 通过ioException()方法检索。
告诉API
祝你好运!