輸入與輸出支持

打印流 PrintStreamPrintWriter

??如果要想通過程序?qū)崿F(xiàn)內(nèi)容的輸出,核心的本質(zhì)一定要依靠OutputStream類完成,但是OutputStream有一個(gè)很大的缺點(diǎn):數(shù)據(jù)輸出操作功能有限:public void write?(byte[] b) throws IOException,所有的數(shù)據(jù)一定要轉(zhuǎn)為字節(jié)數(shù)組后才能輸出,如果現(xiàn)在項(xiàng)目中需要輸出long、double或者Date,這種情況下就必須將這些數(shù)據(jù)變?yōu)樽止?jié)的形式來處理,這樣的處理其實(shí)是非常麻煩的,所以在最初的開發(fā)中為了解決此類的重復(fù)操作,往往由開發(fā)者自行定義一些功能類已簡(jiǎn)化輸出過程。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        String dirPath = "/Users/fzc/Documents/mydir/mldn.txt";
        File file = new File(dirPath);
        PrintUtil util = new PrintUtil(new FileOutputStream(file));
        util.println("姓名:小強(qiáng)子");
        util.print("年齡:");
        util.print(78);
    }
}
class PrintUtil implements AutoCloseable {//實(shí)現(xiàn)數(shù)據(jù)常用的輸出功能
    private OutputStream output;//不管現(xiàn)在如何進(jìn)行輸出操作,核心使用的就是OutputStream

    public PrintUtil(OutputStream output) {
        this.output = output;
    }

    public void print(String str) {//輸出字符串
        try {
            this.output.write(str.getBytes());//輸出
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void println(String str) {
        this.print(str + "\r\n");
    }
    public void print(long num) {
        this.print(String.valueOf(num));
    }
    public void println(long num) {
        this.println(String.valueOf(num));
    }
    @Override
    public void close() throws IOException {
        if (output != null) {
            output.close();
        }
    }
}

??在整個(gè)操作過程之中打印流的設(shè)計(jì)思想的本質(zhì)在于:提高已有類的功能,例如:OutputStream是唯一可實(shí)現(xiàn)輸出的操作標(biāo)準(zhǔn)類,所以應(yīng)該以其為核心根本,但是這個(gè)類的輸出的操作功能有限,所以不方便進(jìn)行輸出各個(gè)類型的數(shù)據(jù),那么就為它做出了一層包裝,所以此時(shí)采用的設(shè)計(jì)思想就是“裝飾設(shè)計(jì)模式”。
??既然已經(jīng)發(fā)現(xiàn)了原始的OutputStream功能的不足,所以為了解決輸出問題,在java.io包中提供了打印流:PrintStream、PrintWriter。

  • PrintStream
public class PrintStream extends FilterOutputStream implements Appendable, Closeable

??構(gòu)造方法:public PrintStream?(OutputStream out)

  • PrintWriter
public class PrintWriter extends Writer

??構(gòu)造方法:public PrintWriter?(OutputStream out)

PrintStream與PrintWriter

??下面使用PrintWriter來實(shí)現(xiàn)數(shù)據(jù)的輸出操作。
范例:數(shù)據(jù)輸出

import java.io.*;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        String dirPath = "/Users/fzc/Documents/mydir/mldn.txt";
        File file = new File(dirPath);
        PrintWriter util = new PrintWriter(new FileOutputStream(file));
        util.println("姓名:小強(qiáng)子");
        util.print("年齡:");
        util.print(78);
        util.close();
    }
}

??從JDK1.5開始,PrintWriter類中追加了格式化輸出的操作支持:
????public PrintWriter format?(String format, Object... args)
范例:格式化輸出

import java.io.*;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        String dirPath = "/Users/fzc/Documents/mydir/mldn.txt";
        File file = new File(dirPath);
        PrintWriter util = new PrintWriter(new FileOutputStream(file));
        String name="張三";
        int age=20;
        double salary=10000.00;
        util.printf("姓名:%s、年齡:%s、月收入:%s",name,age,salary);
        util.close();
    }
}

??比起直接使用OutputStream類,那么使用PrintWriter、PrintStream類的處理操作會(huì)更加簡(jiǎn)單。以后只要是程序進(jìn)行內(nèi)容輸出時(shí)全部使用打印流。

System類對(duì)IO的支持

??System類是一個(gè)系統(tǒng)類,而且是一個(gè)非常常用的系統(tǒng)類,而在該類中提供了和輸入輸出有關(guān)的三個(gè)常量:

  • 標(biāo)準(zhǔn)輸出(顯示器):public static final PrintStream out;
  • 錯(cuò)誤輸出:public static final PrintStream err
  • 標(biāo)準(zhǔn)輸入(鍵盤):public static final InputStream in;
    范例:觀察輸出
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        try {
            Integer.valueOf("a");
        }catch (Exception e){
            System.out.println(e);//白色信息:java.lang.NumberFormatException: For input string: "a"
            System.err.println(e);//紅色信息:java.lang.NumberFormatException: For input string: "a"
        }
    }
}

??System.out和System.err都是同一種類型的,如果使用的是IntelliJ IDEA在進(jìn)行System.err輸出時(shí)會(huì)使用紅色字體,System.out使用白色字體。
??最早設(shè)置兩個(gè)輸出的操作的目的:System.out是輸出那些希望用戶可以看見的信息,System.err是輸出那些不希望用戶看見的信息,如果有需要,也可以修改輸出的位置:

  • 修改out的輸出位置:public static void setOut?(PrintStream out)
  • 修改err的輸出位置:public static void setErr?(PrintStream err)
    范例:修改System.err位置
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        String dirPath = "/Users/fzc/Documents/mydir/mldn_err_print.txt";//定義操作的文件
        File file = new File(dirPath);
        System.setErr(new PrintStream(new FileOutputStream(file)));
        try {
           Integer.valueOf("a");
        }catch (Exception e){
            System.out.println(e);
            System.err.println(e);//輸出到文件中
        }
    }
}

??在System類里面還提供了一個(gè)in的常量,而這個(gè)常量對(duì)應(yīng)的是標(biāo)準(zhǔn)輸入設(shè)備鍵盤的輸入處理,可以實(shí)現(xiàn)鍵盤數(shù)據(jù)輸入。
范例:實(shí)現(xiàn)鍵盤輸入

import java.io.InputStream;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        InputStream in=System.in;//此時(shí)的輸入流為鍵盤輸入
        System.out.print("請(qǐng)輸入信息:");
        byte[] data=new byte[1024];//長(zhǎng)度限制
        int len=in.read(data);
        System.out.println("輸入的內(nèi)容為:"+new String(data,0,len));
        in.close();
        //請(qǐng)輸入信息:asdasda
        //輸入的內(nèi)容為:asdasda
    }
}

??但是這樣的鍵盤輸入處理本身是有缺陷的:如果現(xiàn)在的長(zhǎng)度不足,只能接收部分?jǐn)?shù)據(jù),所以這個(gè)輸入就有可能需要進(jìn)行重復(fù)的輸入流數(shù)據(jù)接收,而且在接收時(shí)還會(huì)涉及到輸入中文,如果對(duì)于中文處理不當(dāng),則也有可能造成亂碼問題。

BufferedReader

??BufferedReader類提供的是一個(gè)緩沖字符輸入流的概念,也就是說利用BufferedReader類可以很好的解決輸入流數(shù)據(jù)讀取問題,這個(gè)類是在最初(JDK1.5之前,1.5后出了一個(gè)更很強(qiáng)大的類代替此類)的時(shí)候提供的最完善的數(shù)據(jù)輸入的處理,之所以使用這個(gè)類來處理,是因?yàn)榇祟愔刑峁┯幸粋€(gè)重要的方法:

  • 讀取一行數(shù)據(jù): public String readLine() throws IOException
BufferedReader

范例:實(shí)現(xiàn)鍵盤數(shù)據(jù)輸入

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        System.out.print("請(qǐng)輸入信息:");
        String msg=reader.readLine();
        System.out.println("輸入的內(nèi)容為:"+msg);
        reader.close();
        //請(qǐng)輸入信息:123
        //輸入的內(nèi)容為:123
    }
}

??在以后的實(shí)際開發(fā)中經(jīng)常會(huì)遇到輸入數(shù)據(jù)的情況,所有輸入數(shù)據(jù)的類型都是通過String描述的,那么這樣就方便了接收者進(jìn)行各種處理。
范例:接收整型輸入并且驗(yàn)證

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        System.out.print("請(qǐng)輸入您的年齡:");
        String msg=reader.readLine();
        if(msg.matches("\\d{1,3}")){
            int age=Integer.valueOf(msg);
            System.out.println("您輸入的年齡:"+msg);
        }else{
            System.err.println("輸入錯(cuò)誤,你輸入的內(nèi)容:"+msg);
        }
        reader.close();
    }
}

??現(xiàn)在Java開發(fā)由鍵盤輸入數(shù)據(jù)的情況并不多見,但是作為一些基礎(chǔ)的邏輯訓(xùn)練還是可以使用鍵盤輸入數(shù)據(jù)的,而鍵盤輸入數(shù)據(jù)的標(biāo)準(zhǔn)做法(JDK1.5之前)就是上面的實(shí)現(xiàn)操作。實(shí)際開發(fā)中所有輸入的數(shù)據(jù)全部為字符串,可以方便驗(yàn)證與進(jìn)行復(fù)雜處理。

Scanner

??java.util.Scanner是從JDK1.5之后追加的一個(gè)程序類,其主要的目的解決輸入流的訪問問題的,可以理解為BufferedReader的替代類,在Scanner類中有如下幾種操作方法:

  • 構(gòu)造方法:public Scanner?(InputStream source)
  • 判斷是否有數(shù)據(jù):public boolean hasNext()
  • 取出數(shù)據(jù):public String next()
  • 設(shè)置分隔符:public Scanner useDelimiter?(String pattern)
    范例:使用Scanner實(shí)現(xiàn)鍵盤輸入字符串
import java.util.Scanner;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("請(qǐng)輸入您的姓名:");
        if (sc.hasNext()) {
            System.out.println("您輸入的姓名:" + sc.next());//換行不算輸入
        } else {
            System.err.println("輸入有誤,未獲取到內(nèi)容");
        }
    }
}

范例:使用Scanner實(shí)現(xiàn)鍵盤數(shù)字輸入

import java.util.Scanner;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("請(qǐng)輸入您的年齡:");
        if (sc.hasNextInt()) {//判斷是否有整數(shù)輸入
            int age = sc.nextInt();//可以直接獲取數(shù)字
            System.out.println("您輸入的年齡:" + age);
        }else{
            System.err.println("輸入有誤,未獲取到內(nèi)容");
        }
    }
}

??使用Scanner輸入數(shù)據(jù)還有一個(gè)最大的的特點(diǎn)是可以直接利用正則進(jìn)行驗(yàn)證判斷。
范例:輸入一個(gè)人的生日

import java.util.Scanner;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        String birthdayRegex="\\d{4}-\\d{2}-\\d{2}";
        Scanner sc = new Scanner(System.in);
        System.out.println("請(qǐng)輸入您的生日:");
        if (sc.hasNext(birthdayRegex)) {
            System.out.println("您輸入的生日:" + sc.next());//換行不算輸入
        } else {
            System.err.println("輸入有誤,未獲取到內(nèi)容");
        }
    }
}

范例:使用Scanner讀取文件信息

import java.io.File;
import java.util.Scanner;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        String dirPath = "/Users/fzc/Documents/mydir/mldn.txt";//定義操作的文件
        File file = new File(dirPath);
        Scanner sc = new Scanner(file);
        sc.useDelimiter("\r\n");//默認(rèn)以空格作為換行,設(shè)置以\r\n為換行符
        while (sc.hasNext()) {
            System.out.println(sc.next());
        }
    }
}

??現(xiàn)在可以發(fā)現(xiàn)Scanner的整體設(shè)計(jì)要好于BufferedReader,而且要比InputStream類讀取更方便。在以后的開發(fā)中,如果程序需要輸出數(shù)據(jù),則要使用打印流,輸入數(shù)據(jù)使用Scanner或BufferedReader。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容