要使用标准输入流 System.in ,比较麻烦,首先需要构建一个 Scanner 对象,并与 System.in 关联。

  1. import java.util.Scanner;
  2. Scanner in = new Scanner(System.in);

就可以调用各种 API 来输入

  1. // 读取一行,以换行符结束
  2. String str = in.nextLine();
  3. // 读取一个单词,以空白符作为分隔符,换行符结束
  4. String str = in.next();
  5. // 读取整数
  6. String str = in.nextInt();
  7. // 读取浮点数
  8. String str = in.nextDouble();
  9. // 检测输入中是否还有其他单词
  10. boolean b = in.hasNext();

使用 Scanner 的输入是可见的,可以使用 Console 来读取密码,让密码不可见

  1. Console cons = System.console();
  2. String data = cons.readLine("User name: ");
  3. char[] passwd = cons.readPassword("Password: ");

注意:Console 类仅在 IDE 外部可用,也就是说你必须手动编译代码运行。否则, Console 会返回 null

为了安全起见,返回的密码存放在一维字符数组中,而不是字符串中。在对密码进行处理之后,应该马上用一个填充值覆盖数组元素。
采用 Console 对象处理输入不如采用 Scanner 方便。每次只能读取一行输入,而没有能够读取一个单词或一个数值的方法。但,你可以针对一行输入的内容进行处理,以达到这样的效果。

格式化输出

Java SE 5.0 沿用了 C 语言库函数中的 printf 方法。
转换符:

| 转换符 | 说 明 | 示 例 | | —- | —- | —- |

| %s | 字符串类型 | “NeFeed” |

| %c | 字符类型 | ‘m’ |

| %b | 布尔类型 | true OR false |

| %d | 整数类型(十进制) | 10 |

| %x | 整数类型(十六进制) | FF |

| %o | 整数类型(八进制) | 77 |

| %f | 浮点类型 | 6.66 |

| %a | 十六进制浮点类型 | 0x1.fccdp3 |

| %e | 指数类型 | 6.23e+24 |

| %g | 通用浮点类型(f和e类型中较短的) | 42.5000 |

| %h | 散列码 | ‘A’ -> 41 |

| %% | 百分比类型 | % |

| %n | 换行符 | 相当于”\n”换行作用 |

| %t(日期转换符) | 日期和时间 | 2020-07-24 |

还有一些控制格式化输出的各种标志:

| 标志 | 目的 | 举例 | 结 果 | | —- | —- | —- | —- |

| + | 为正数或者负数添加符号 | (“%+d”,15) | +15 |

| − | 左对齐 | (“n%-5dn”,25) | n25 n |

| 0 | 数字前面补 0 | (“%04d”, 21) | 0021 |

| 空格 | 在整数之前添加指定数量的空格 | (“n% 4dn”, 99) | n 99n |

| , | 以“,”对数字分组(英式数字计数法) | (“%,f”, 9999.99) | 9,999.990000 |

| ( | 使用括号包含负数 | (“%(f”, -99.99) | (99.990000) |

| # | 如果是浮点数则包含小数点,如果是 16 进制或 8 进制则添加 0x 或 0 | (“%#x”, 99)
(“%#o”, 99)
(“%#f”, 99) | 0x63
0143
99. |

| < | 格式化前一个转换符所描述的参数 | (“%f”, 99.45)
(“%d%<x”, 159) | 99.450000
159 9F |

| $ | 被格式化的参数索引。注意,参数索引从 1 开始 | (“%1$d %1$x”, 159) | 159 9F |

可以使用 %s 转换符格式化任意的对象。对于任意实现了 Formattable 接口的对象都将调用 formatTo 方法;否则将调用 toString 方法。
可以使用静态的String.format方法创建一个格式化的字符串,而不打印输出

  1. String message = String.format("Hello, %s. Next year, you'll be %d", name, age);

更多内容可以看 文档 和下面这张图来规范使用 printf()
format_syntax
许多格式化规则是本地环境特有的。例如,在德国,组分隔符是句号而不是逗号,Monday 被格式化为 Montag。

文件输入与输出

可以使用 Scanner 来进行文件读取。Scanner 读取文件,需要 File 对象来进行构造:

  1. // 抛出 IOException 异常
  2. public static void main(String[] args) throws IOException {
  3. Scanner in = new Scanner(Paths.get("myfile.txt"), "UTF-8");
  4. while(in.hasNextLine()) {
  5. System.out.println(in.nextLine());
  6. }
  7. }

写入文件,就要构造 PrintWriter 对象,与 Scanner 不同,它只需要提供文件名:

  1. PrintWriter out = new PrintWriter("myfile.txt", "UTF-8");

如果文件不存在,则创建该文件。
如果,你像 PrintWriter 来构建 Scanner 是不会报错的,因为这是 Scanner 允许的,Scanner 会将字符串解释为数据,而不是文件名:

  1. Scanner in = new Scanner("myfile.txt");
  2. System.out.println(in.nextLine()); // output: myfile.txt

最后来说一下文件名的格式和文件的相对路径。
在 Linux 中,文件路径有一种写法:/home/me/mydirectory/myfile.txt
但在 Windows 中,可以有多种写法:C:\\mydirectory\\myfile.txt or C:/mydirectory/myfile or C:\\mydirectory/myfile
可以看到,在 Windows 中,不仅可以使用 Windows 自身的写法,还可以使用 Linux 的写法,甚至可以将两者融合。需要注意的是 Windows 写法中,反斜杠需要考反斜杠转移,写起来比较繁琐。

还有一个奇淫技巧,如果你当前文件目录在 D 盘,路径 /mydirecotry/myfile 等于 D:\mydirecotry\myfile 。了解一下即可。

你在命令行中运行 Java 文件时,该启动路径就是你当前所在的路径。但是在 IDE 中,就可能不是这样的。个人实测,在 IDEA 中,你的启动路径就是你当前打开的项目路径,比如,你现在打开的是,D:\language\java 这个项目,你运行的是 D:\language\java\src\Welcome.java 这个文件,它还是会将启动路径定到 D:\language\java 这个路径上。
当然,如果不知道启动路径,可以用下面的方式来查看:

  1. System.out.println(System.getProperty("user.dir"));

IDEA 启动路径的一个例子

我的项目代码在 D:\language\java 中,树形图为:

  1. java
  2. ├── java.iml
  3. └── src
  4. ├── Main.java
  5. └── myfile.txt

我现在运行 Main.java 读取 myfile.txt 中的内容,对于文件路径有两种方式:绝对路径和相对路径

  • 绝对路径
  1. // 因为当前目录在 D 盘,所以还可以这样写。但如果是别的盘,就不能这样写
  2. // Path path = Paths.get("/language/java/src/myfile.txt");
  3. Path path = Paths.get("D:\\language\\java\\src\\myfile.txt");
  4. // or D:/language/java/src/myfile.txt
  5. Scanner in = new Scanner(path, "UTF-8");
  6. System.out.println(in.nextLine());
  7. while(in.hasNextLine()) {
  8. System.out.println(in.nextLine());
  9. }
  • 相对路径
  1. // 因为启动目录是 D:\language\java, 所以这里必须加上 src
  2. // 如果直接写 myfile.txt, IDEA 会找 D:\language\java\myfile.txt 这个文件
  3. Path path = Paths.get("src/myfile.txt");
  4. // or src\\myfile.txt
  5. Scanner in = new Scanner(path, "UTF-8");
  6. System.out.println(in.nextLine());
  7. while(in.hasNextLine()) {
  8. System.out.println(in.nextLine());
  9. }