🍧 Peach

蜜桃学代码

IO - 标准设备输入/输出


一、标准设备输入/输出类 - System

System是Java系统中一个最常使用的类:Java的系统类。

%%{
    init: {
        'themeVariables': {
            'fontSize': '13px'
        }
    }
}%%
graph LR
t(("System
(系统类)")):::p --> T subgraph 静态方法 T([静态方法]):::p T --> 1("标准输出 out
标准输入 in
标准错误输出 err"):::lp T -.- 2("访问外部定义的属性和环境变量"):::info T -.- 3("加载文件和库"):::info T -.- 4("快速复制数组"):::info T -.- 5("取得系统时间:
System.currentTimeMillis()"):::info T -.- 6("系统退出命令:System.exit()"):::info end t --> T2(["静态成员变量"]):::b subgraph "静态成员变量
(用于连接到标准输入/输出控制设备(键盘和控制台))
" T2 --> 7("标准输出流
static PrintStream out"):::lb T2 --> 8("标准错误输出流
static PrintStream err"):::lb T2 --> 9("标准输入流
static PrintStream in"):::lb end 7 -.- 7t("System.out.print()
System.out.println()
"):::lg 8 -.- 8t("System.err.print()"):::lg 9 -.- 9t("System.in.read()
System.in.read(b)
"):::lg classDef p fill:#ddaebd classDef b fill:#aab7d2 classDef g fill:#9ac5bb classDef lp fill:#f4e4e9 classDef lb fill:#d9dfeb classDef lg fill:#ddebe6 classDef info color:#4e4e52,stroke-dasharray: 3 3, stroke-width: 2px

① out 标准输出流

输出消息到控制台

// ------ * 编写一行输出数据 ----------------------------------
System.out.println(data);

// ------ 输出各种类型的数值 -----------------------------------
void print(boolean b); // 打印boolean值
void print(char c); // 打印字符
void print(char[]s); // 打印字符数组
void print(double d); // 打印双精度浮点数
void print(float f); // 打印浮点数
void print(int i); // 打印整数
void print(long l); // 打印long整数
void print(Object obj); // 打印对象
void print(String s); // 打印字符串

// ------ 输出各种类型的数值 + 换行 -------------------------------
void println(boolean x); // 打印boolean值,然后终止行
void println(char x); // 打印字符,然后终止该行
void println(char[]x); // 打印字符数组,然后终止该行
void println(double x); // 打印double,然后终止该行
void println(float x); // 打印float,然后终止该行
void println(int x); // 打印整数,然后终止该行
void println(long x); // 打印long,然后终止该行
void println(Object x); // 打印Object,然后终止该行
void println(String x); // 打印String,然后终止该行

// ------ 直接输出字节数据(字节流) --------------------------------
void write(int b); // 将指定的字节写入此流
void write(byte[] buf, int off, int len); // 将len字节从指定的初始偏移量为off的byte数组写入此流

② err 标准错误输出流

输出错误消息到控制台

System.err.println(data);   /* 此输出流用于显示错误消息,或者显示那些
即使用户输出流(变量out的值)已经重定向到通常不被连续监视的某一文件或其他目标,
也应该立刻引起用户注意的其他信息。 */

③ in 标准输入流

接收键盘输入

read()          // 读取一个字节
read(byte[] b) // 读取一个字节数组

1. read()

public class TestSystemInRead {
public static void main(String args[]) {
try {
int c;
while((c=System.in.read())!=0){ // 从控制台读入一个字节(8bit)
System.out.write(c); // 输出一个字节
}
} catch (Exception e) {
}
}
}

// 运行该程序,在控制台输入一段字符后按回车键,就会调用read()函数的循环,
// 每读到一个字节就会输出一个字节,因此回车前输入的字符串就会原样输出。

2. read(byte[] b)

/**
* 首先创建了一个长度为100的字节数组,表示一次可以读取100个字节。
* 然后使用read(byte[] b)读取100个字节到byte中,再调用write()函数输出这个字节数组到控制台中。
*/
public class TestSystemInReadByte {
public static void main(String args[]) {
try {
byte[]b=new byte[100]; // 创建字节数组
System.in.read(b); // 读取到数组中
System.out.write(b,0,100); // 输出字节数组
} catch (Exception e) {
}
}
}
// 运行该程序,输入一个字符串,回车后就会输出回车前字符串的前100个字符。
// 如果你输入的字符串长度小于100,那么为了补全100个字节,剩余的字节将会使用方框“□”表示,实际上是这个字节没有数据。
// 如果输入的字符串长度大于100,多余的字节就会被抛弃。


二、控制台读写类 - Console

  • Console类优点:

      %%{
        init: {
            'themeVariables': {
                'fontSize': '13px'
            }
        }
    }%%
    graph LR
    A(["System 缺点"]):::g
    B(["Console 优点"]):::p
    A -.- 1("读入的字节数组长度100的限制:若字符串长度
    小于100将会使用方框代替,若大于100将会被抛弃。"):::lg B -.- 2("不需要捕捉异常,该函数没有抛出异常"):::lp B -.- 3("不需要将字节数组转化为字符串,直接读入即字符串"):::lp B -.- 4("可以完整读取一行输入并完整输出,没有抛弃和填充"):::lp classDef p fill:#ddaebd classDef b fill:#aab7d2 classDef g fill:#9ac5bb classDef lp fill:#f4e4e9 classDef lb fill:#d9dfeb classDef lg fill:#ddebe6 classDef info fill:#f6f6f7,color:#737379,stroke-dasharray: 3 3, stroke-width: 2px
  • Console类方法可访问与当前Java虚拟机关联的基于字符的控制台设备(若有),常指键盘。

    虚拟机是否具有控制台取决于底层平台,还取决于调用虚拟机的方式:

      %%{
        init: {
            'themeVariables': {
                'fontSize': '14px'
            }
        }
    }%%
    graph 
    T(["访问与虚拟机关联的控制台设备"]):::p
    T --> A("① 虚拟机从交互式命令行启动,
    且没有重定向标准输入和输出流"):::lp T --> B("② 虚拟机自动启动
    (如,由后台作业调度程序启动)"):::lg A -.- a(["控制台存在"]):::p B -.- b(["无控制台"]):::g a -.- |"连接到设备
    (键盘)"|1("由此类唯一的实例表示
    (调用 System.console() 获得)"):::lp a -.- |"无可用设备"|2("对该方法的调用返回null"):::info %% 将由此类唯一的实例表示
    (可通过调用 System.console() 获得)") classDef p fill:#ddaebd classDef b fill:#aab7d2 classDef g fill:#9ac5bb classDef lp fill:#f4e4e9 classDef lb fill:#d9dfeb classDef lg fill:#ddebe6 classDef info fill:#f6f6f7,color:#737379,stroke-dasharray: 3 3, stroke-width: 2px

① 读取信息 readLine()

从控制台读取输入的字符串

System.console().readLine();
/** 
* 使用了System.console()函数取得了Console对象,
* 然后使用readLine()函数即可读取一行字符串的输入。该函数在用户执行回车时调用。
*/
public class TestConsole {

public static void main(String args[]) {
while (true) {
String str = System.console().readLine(); // 取得输入字符串
System.out.println(str); // 输出字符串
}
}

}

② 输出信息 printf()

从控制台输出消息

System.console().printf(str);

注:其读写操作是同步的,以保证关键操作能完整完成。因此调用readLine()、printf()时可能阻塞。

③ 读取密码 readPassword()

应用程序需要读取密码或其他安全数据,则应使用 readPassword()readPassword(String, Object…),并在执行后手工将返回的字符数组归零,以最大限度地缩短内存中敏感数据的生存期。

读取密码

System.console().readPassword()
public class TestConsolePassword {

public static void main(String args[]) {
while (true) {
char password[] = System.console().readPassword(); // 取得密码
System.out.println(password); // 输出字符串
}
}

}

// 它直接监控键盘的输入,回车后即可取得密码字符串。

读取密码时添加提示信息

System.console().readPassword("[%s]", "请输入密码:");

// 字符串“请输入密码:”将作为提示信息显示在控制台窗口中。



- end -


🔖 笔记来自:《Java高手真经(编程基础卷)》