1.读取输入
通过调用System.out.println即可将输出打印到“标准输出流”(即控制台窗口)。 从“标准输入流” System.in中读取并不是那么简单。 要读取控制台输入,首先要构造一个附加到System.in的 Scanner:
Scanner in = new Scanner(System.in);
现在,您可以使用Scanner类的各种方法来读取输入。 例如,nextLine方法读取一行输入。
System.out.print("What is your name? ");
String name = in.nextLine();
在这里,我们使用nextLine方法,因为输入可能包含空格。
要阅读单个单词(由空格分隔),用next方法
String firstName = in.next();
要读取整数,请使用nextInt方法
System.out.print("How old are you? ");
int age = in.nextInt();
同样,nextDouble方法读取下一个浮点数。代码清单3.2中的程序询问用户的姓名和年龄,然后显示如下消息:
Hello, Cay. Next year, you'll be 57
最后,注意这一行
import java.util.*;
在程序开始时。 Scanner类在java.util包中定义。 每当使用基本java.lang包中未定义的类时,都需要使用import指令。
Listing 3.2InputTest/InputTest.java
1 import java.util.*;
2 public class InputTest
3 {
4 public static void main(String[] args)
5 {
6 Scanner in = new Scanner(System.in);
7
8 // get first input
9 System.out.print("What is your name? ");
10 String name = in.nextLine();
11
12 // get second input
13 System.out.print("How old are you? ");
14 int age = in.nextInt();
15
16 // display output on console
17 System.out.println("Hello, " + name + ". Next year, you'll be " + (age + 1));
18 }
19 }
注意:The Scanner类不适合从控制台读取密码,因为任何人都可以清楚看到输入内容。 Java 6为此专门引入了一个Console类。 要读取密码,请使用以下代码:
Console cons = System.console();
string userName= cons.readLine(“用户名:”);
char [] passwd = cons.readPassword(“ Password:”);
出于安全性考虑 原因是,密码是以字符数组而不是字符串返回的。 处理完密码后,应立即使用填充值覆盖数组元素。使用控制台对象进行输入处理不如使用Scanner类进行输入处理方便。 您必须一次读取输入内容, 没有读取单个单词或数字的方法.
java.util.Scanner
•Scanner(InputStream in)
从给定的输入流构造一个Scanner对象。
•String nextLine()
读取输入的下一行。
•String next()
读取输入的下一个单词(由空格分隔)。
•int nextInt()
•double nextDouble()
读取并转换表示整数或浮点数的下一个字符序列。
•boolean hasNext()
测试输入中是否还有另一个单词.
•boolean hasNextInt()
•boolean hasNextDouble()
测试下一个字符序列是整数还是浮点数。
java.lang.System
•static Console console()
返回一个Console对象,以便通过控制台窗口与用户进行交互(如果可能的话),否则返回null。 控制台对象可用于在控制台窗口中启动的任何程序。 否则,可用性取决于系统。
java.io.Console
•static char [] readPassword((String prompt, Object... args)
•static String readLine((String prompt, Object... args)
显示提示并读取用户 输入,直到输入行的末尾。args参数可用于提供格式参数。
2.格式化输出
您可以使用语句System.out.print(x)在控制台上打印一个数字x,该命令将以该类型的最大非零位数打印x。 例如,
double x = 10000.0 / 3.0;
System.out.print(x);
输出:
3333.3333333333335
如果要显示美元和美分,这是一个问题。在Java的早期版本中,格式化数字有点麻烦。 幸运的是,Java 5从C库中恢复了古老的printf方法。 例如,
System.out.printf("%8.2f", x);
打印x,其字段宽度为8个字符,精度为2个字符。 也就是说,打印输出包含一个前导空格和七个字符。
3333.33
可以向printf提供多个参数。 例如:
System.out.printf("Hello, %s. Next year, you'll be %d", name, age);
每个以%字符开头的格式说明符都将替换为相应的参数。 以格式说明符结尾的转换字符表示要格式化的值的类型:f是浮点数,s是字符串,d是十进制整数。 表3.5列出了所有转换字符。
另外,您可以指定控制格式化输出外观的标志。 表3.6列出了所有标志。 例如,逗号标志添加了分组分隔符。
System.out.printf("%,.2f", 10000.0 / 3.0);
输出
3,333.33
您可以使用多个标志例如“%,(.2f”使用组分隔符并将负数括在括号中。
您可以使用静态String.format方法创建带格式的字符串,而无需打印它:
String message = String.format("Hello, %s. Next year, you'll be %d", name, age);
我们简要讨论printf方法的日期和时间格式设置选项。 对于新代码,应使用java.time包的方法。 但是,您可以在旧版代码中遇到Date类和相关的格式设置选项。格式由两个字母组成,以t开头,以表3.7的一个字母结尾。 例如,
System.out.printf("%tc", new Date());
以以下格式打印当前日期和时间
Mon Feb 09 18:05:19 PST 2021
如表3.7所示,某些格式仅产生给定日期的一部分,例如,仅一天或一个月。 如果您必须多次提供日期来格式化每个部分,那将有点低效。 因此,格式字符串可以指示要格式化的参数的索引。 索引必须紧随%之后,并且必须以$结尾。 例如,
System.out.printf("%1$s %2$tB %2$te, %2$tY", "Due date:", new Date());
Due date: February 9, 2015
或者,您可以使用 产生与前面的语句相同的输出。 注意:参数索引值以1开头,而不是以0:%1 $...格式化第一个参数。 这避免了与0标志的混淆. 现在,您已经看到了printf方法的所有功能。 图3.6显示了格式说明符的语法图 要从文件中读取,请构造一个Scanner对象,如下所示: 如果文件名包含反斜杠,请记住使用一个附加的反斜杠对每个转义符进行转义:“ c:\\ mydirectory \\ myfile.txt” 注意:在此,我们指定UTF-8字符编码,这对于Internet上的文件是通用的(但不是通用的)。 阅读文本文件时,您需要知道字符编码( 如果省略字符编码,则使用运行Java程序的计算机的“默认编码”。 这不是一个好主意-程序可能会在不同的地方运行,因此其运行可能有所不同。 现在,您可以使用已经介绍过的任何Scanner方法从文件中读取文件。要写入文件,请构造一个PrintWriter对象。 在构造函数中,提供文件名和字符编码: 如果该文件不存在,则会创建它。 您可以像打印到System.out时一样使用print,println和printf命令。 注意:可以使用字符串参数构造Scanner,但是扫描程序会将字符串解释为数据,而不是文件名。 例如,如果在 注:当您指定相对文件名时,例如“ myfile.txt”,“ mydirectory / myfile.txt”或“ ../myfile.txt”,该文件相对于Java所在的目录 虚拟机已启动。 如果从命令外壳启动程序,则通过执行 java MyProg 起始目录是命令外壳的当前目录。 但是,如果使用集成开发环境,它将控制开始目录。 您可以通过以下调用找到目录位置: 如果在查找文件时遇到麻烦,请考虑使用绝对路径名,例如 “ c:\\ mydirectory \\ myfile.txt” 如您所见,您可以像使用System.in和System.out一样轻松地访问文件。 有一个问题:如果使用不存在的文件构造Scanner或使用无法创建的文件名构造PrintWriter,则会发生异常。 例如,Java编译器认为这些异常比“除以0”异常更为严重。 您可以通过使用throws子句标记main方法来做到这一点,如下所示: 注意:从命令外壳启动程序时,可以使用外壳的定向语法并将任何文件附加到System.in和System.out: java.util.Scanner •Scanner(String data) java.io.PrintWriter java.nio.file.PathSystem.out.printf("%s %tB %
3.文件输入输出
Scanner in = new Scanner(Path.of("myfile.txt"), StandardCharsets.UTF_8);
PrintWriter out = new PrintWriter("myfile.txt", StandardCharsets.UTF_8);
Scanner in = new Scanner(“ myfile.txt”)// error?
中调用Scanner; 然后,扫描程序将看到十个字符的数据:'m','y','f',依此类推。
String dir = System.getProperty(“ user.dir”);
或
”/home/me/mydirectory/myfile.txt”。public static void main(String[] args) throws IOException
{
Scanner in = new Scanner(Path.of("myfile.txt"), StandardCharsets.UTF_8);
. . .
}
java MyProg
然后,您无需担心处理IOException的问题。
•Scanner(Path p, String encoding)
构造一个使用给定字符编码从给定路径读取数据的扫描器。
构造一个从给定的string读取数据的扫描器。
•PrintWriter(String fileName)构造一个PrintWriter,该PrintWriter将数据写入具有给定文件名的文件中。
•static Path of(String pathname)
根据给定的路径名构造路径