【Java基础知识】IO流–标准输入输出流、打印流PrintStream

  • Post author:
  • Post category:java


1 标准输入流

public static final InputStream in"标准"输入流。

此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。

从键盘获取数据的3种方式:

(1)main方法的args接收参数:java param1 param2 Xxx. java

(2)通过使用Scanner类【Jdk 1.5版本后】

Scanner sc = new Scanner(System.in);

String s = sc.nextLine();

int x = sc.nextInt()

(3)通过字符缓冲流包装标准输入流,来实现

把字节流转换成字符流,然后通过字符缓冲流操作。

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

使用案例:通过字符缓冲流来获取键盘录入的数据。

public class SystemInDemo {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入一个字符串:");
        String line = br.readLine();
        System.out.println("你输入的字符串是:" + line);
        System.out.println("请输入一个整数:");
        // int i = Integer.parseInt(br.readLine());
        line = br.readLine();
        int i = Integer.parseInt(line);
        System.out.println("你输入的整数是:" + i);
    }
}

2 标准输出流

public static final PrintStream out"标准"输出流。
标准输出流的实例是打印流【PrintStream】。

此流已打开并准备接受输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。

public class SystemOutDemo {
    public static void main(String[] args) {
        System.out.println("Java");
        // 获取标准输出流对象
        PrintStream ps = System.out;
        ps.println("Java");
        ps.println();
    }
}

3 打印流PrintStream、PrintWriter

PrintStream类提供了一系列的print和println()方法,可以实现将基本类型的格式化成字符串输出。

System.out就是PrintStream类的一个实例对象。

3.1 字节打印流PrintStream

构造函数:

PrintStream(OutputStream out)
PrintStream(OutputStream out,boolean auotflush)
PrintStream(OutputStream out,boolean auotflush, String encoding)

其中autoflush控制在Java中遇到换行符(\n)时是否自动清空缓冲区,encoding是指定编码方式。println方法与print方法的区别是:println()等于print(“\n”)。Java的PrintStream对象具有多个重载的print和println方法,它们可输出各种类型(包括Object)的数据。对于基本数据类型的数据,print和println方法会先将它们转换成字符串的形式后再输出,而不是输出原始的字节内容,对于一个非基本数据类型的对象,print和println方法会先调用对象的toString方法,然后再输出toString方法返回的字符串。

【PrintStream源码部分内容分析:】

public class PrintStream extends FilterOutputStream{

    private final boolean autoFlush;
    private boolean trouble = false;
    private BufferedWriter textOut; //字符缓冲流
    private OutputStreamWriter charOut; //转换流,作为字符缓冲流的参数

    //创建不带自动刷新的打印流。
    public PrintStream(OutputStream out) {
        this(out, false);
    }
    //创建可设置自动刷新的打印流
    public PrintStream(OutputStream out, boolean autoFlush) {
        this(autoFlush, requireNonNull(out, "Null output stream"));
    }
    //创建给定autoFlush和encoding的打印流
    public PrintStream(OutputStream out, boolean autoFlush, String encoding)
        throws UnsupportedEncodingException{
        this(autoFlush,requireNonNull(out, "Null output stream"),toCharset(encoding));           
    }   

    /* 私有构造 */
    private PrintStream(boolean autoFlush, OutputStream out) {
        super(out);
        this.autoFlush = autoFlush;
        this.charOut = new OutputStreamWriter(this);
        this.textOut = new BufferedWriter(charOut);
    }
    /* 私有构造 */
    private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
        super(out);
        this.autoFlush = autoFlush;
        this.charOut = new OutputStreamWriter(this, charset);
        this.textOut = new BufferedWriter(charOut);
    }       
    /*检测IO流对象,确定IO是打开的状态 */
    private void ensureOpen() throws IOException {
        if (out == null) throw new IOException("Stream closed");      
    }
    //刷新IO流
    public void flush() {
        synchronized (this) {
            try {
                ensureOpen();
                out.flush();
            }
            catch (IOException x) {
                trouble = true;
            }
        }
    }
    public void write(int b) {
        try {
            synchronized (this) {
                ensureOpen();
                out.write(b);
                if ((b == '\n') && autoFlush)
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }
    public void write(byte buf[], int off, int len) {
        try {
            synchronized (this) {
                ensureOpen();
                out.write(buf, off, len);
                if (autoFlush)
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }
    private void write(char buf[]) {
        try {
            synchronized (this) {
                ensureOpen();
                textOut.write(buf);
                textOut.flushBuffer();
                charOut.flushBuffer();
                if (autoFlush) {
                    for (int i = 0; i < buf.length; i++)
                        if (buf[i] == '\n')
                            out.flush();
                }
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }
    private void write(String s) {
        try {
            synchronized (this) {
                ensureOpen();
                textOut.write(s);
                textOut.flushBuffer();
                charOut.flushBuffer();
                if (autoFlush && (s.indexOf('\n') >= 0))
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }
    //换行,根据flushBuffer设置,选择是否自动刷新
    private void newLine() {
        try {
            synchronized (this) {
                ensureOpen();
                textOut.newLine();
                textOut.flushBuffer();
                charOut.flushBuffer();
                if (autoFlush)
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }
    /*以下是print(X x)方法的重载*/
    public void print(boolean b) {
        write(b ? "true" : "false");
    }
    public void print(char c) {
        write(String.valueOf(c));
    }
    public void print(int i) {
        write(String.valueOf(i));
    }
    public void print(long l) {
        write(String.valueOf(l));
    }
    public void print(float f) {
        write(String.valueOf(f));
    }
    public void print(double d) {
        write(String.valueOf(d));
    }
    public void print(char s[]) {
        write(s);
    }
    public void print(String s) {
        if (s == null) {
            s = "null";
        }
        write(s);
    }
    public void print(Object obj) {
        write(String.valueOf(obj));
    }
    //换行
    public void println() {
        newLine();
    }
    /*以下是println(X x)方法的重载*/
    public void println(boolean x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void println(char x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void println(int x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void println(long x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void println(float x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void println(double x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void println(char x[]) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
    public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }
}

3.2 字符打印流PrintWriter

IO包中提供了一个与PrintStream对应的PrintWriter类,PrintWriter即使遇到换行符(\n)也不会自动清空缓冲区,只在设置了autoflush模式下使用了println方法后才自动清空缓冲区。 PrintWriter相对PrintStream最有利的一个地方就是println方法的行为,在Windows的文本换行是”\r\n”, 而Linux下的文本换行是”\n”,如果我们希望程序能够生成平台相关的文本换行,而不是在各种平台下都用”\n”作为文本换行,我们就应该使用PrintWriter的println方法时,PrintWriter的println方法能根据不同的操作系统而生成相应的换行符。

【PrintWriter源码部分内容分析:】

字节流的print(), println()方法的源码分析,实际上底层调用的是该类成员变量,Writer类对象out的write()方法。out成员变量通过构造初始化。

字节流的print(), println()方法的源码分析,实际上底层调用的是
该类成员变量,Writer类对象out的write()方法。out成员变量通过构造初始化。
public class PrintWriter extends Writer{
    protected Writer out;
    private final boolean autoFlush;//是否自动刷新
    /*
    如果为 true,则每当写入 byte 数组、调用其中一个 println 方法
    或写入换行符或字节 ('\n') 时都会刷新输出缓冲区
    */
    private boolean trouble = false;    
    public PrintWriter (Writer out) {
        this(out, false);
    }
    public PrintWriter(Writer out,boolean autoFlush) {                  
        super(out);
        this.out = out;
        this.autoFlush = autoFlush;     
    }
    /*print()可以操作任何类型的数据,下面,
      我们看看源码中各种类型数据的处理 */
    public void print(String s) {
        if (s == null) { s = "null"; }
        write(s);
    }
    public void write(String s) {
        write(s, 0, s.length());
    }
    //调用字符流out的write方法
    public void write(String s, int off, int len) {
        try {
            synchronized (lock) {
                ensureOpen();
                out.write(s, off, len);
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }
    /*检查out,确保流是打开的*/
    private void ensureOpen() throws IOException {
        if (out == null)
            throw new IOException("Stream closed");
    }   
    /*
     print()可以操作,boolean,int,long, float, double,chae[]
     Object等类型
    */
    public void print(boolean b) {
        write(b ? "true" : "false");
    }
    public void print(char c) {
        write(c);
    }
    public void print(int i) {
        write(String.valueOf(i));
    }   
    public void print(long l) {
        write(String.valueOf(l));
    }   
    public void print(float f) {
        write(String.valueOf(f));
    }   
    public void print(double d) {
        write(String.valueOf(d));
    }   
    public void print(char s[]) {
        write(s);
    }
    public void print(Object obj) {
        write(String.valueOf(obj));
    }
/*println()换行,源码分析:如果autoFlush为true
则调用println()还启用了自动刷新的功能。
*/
    public void println() {
        newLine();
    }
    private void newLine() {
        try {
            synchronized (lock) {
                ensureOpen();
                out.write(lineSeparator);
                if (autoFlush)
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }   
}



版权声明:本文为zhuwenchao90原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。