扫描
编程 I / O 通常涉及转换人们喜欢使用的整齐格式的数据,为了帮助你完成这些工作,Java 平台提供了两个 API,扫描器 API 将输入分解为与数据位相关联的单个标记,格式化 API 将数据组装成格式良好、可读的形式。
Scanner 类型的对象对于将格式化输入分解为标记并根据其数据类型转换单个标记非常有用。
将输入分解为标记
默认情况下,扫描器使用空格分隔标记(空格字符包括空格、制表符和行终止符,有关完整列表,请参阅 Character.isWhitespace 的文档),要了解扫描的工作原理,让我们看看 ScanXan,这是一个读取 xanadu.txt 中单个单词并打印出来的程序,每行一个单词。
import java.io.*;
import java.util.Scanner;
public class ScanXan {
public static void main(String[] args) throws IOException {
Scanner s = null;
try {
s = new Scanner(new BufferedReader(new FileReader(“xanadu.txt”)));
while (s.hasNext()) {
System.out.println(s.next());
}
} finally {
if (s != null) {
s.close();
}
}
}
}
请注意,ScanXan 在使用扫描器对象完成后会调用 Scanner 的 close 方法,即使扫描器不是流,你也需要将其关闭以指示你已完成其底层流。
ScanXan 的输出如下所示:
In
Xanadu
did
Kubla
Khan
A
stately
pleasure-dome
…
要使用其他标记分隔符,请调用 useDelimiter(),指定正则表达式,例如,假设你希望标记分隔符为逗号,可选地后跟空格,你会调用:
s.useDelimiter(“,\\s*”);
转换单个标记
ScanXan 示例将所有输入标记视为简单的 String 值,Scanner 还支持所有 Java 语言的原始类型(char 除外)的标记,以及 BigInteger 和 BigDecimal,此外,数值可以使用数千个分隔符。因此,在美国语言环境中,Scanner 将字符串“32,767”正确地读取为一个整数值。
我们必须提到语言环境,因为千位分隔符和小数符号是特定于语言环境的,因此,如果我们未指定扫描器应使用美国语言环境,则以下示例将无法在所有语言环境中正常运行。这通常不必担心,因为你的输入数据通常来自使用相同语言环境的源,但是这个例子是 Java 教程的一部分,并且分布在世界各地。
ScanSum 示例读取 double 值列表并将其相加,这是源码:
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.Locale;
public class ScanSum {
public static void main(String[] args) throws IOException {
Scanner s = null;
double sum = 0;
try {
s = new Scanner(new BufferedReader(new FileReader(“usnumbers.txt”)));
s.useLocale(Locale.US);
while (s.hasNext()) {
if (s.hasNextDouble()) {
sum += s.nextDouble();
} else {
s.next();
}
}
} finally {
s.close();
}
System.out.println(sum);
}
}
这是示例输入文件 usnumbers.txt。
8.5
32,767
3.14159
1,000,000.1
输出字符串是“1032778.74159”,在某些语言环境中,句点将是不同的字符,因为 System.out 是 PrintStream 对象,并且该类不提供重写默认语言环境的方法,我们可以覆盖整个程序的语言环境 — 或者我们可以只使用格式化,如下一个主题格式化中所述。
上一篇:缓冲流