您好,欢迎来到二三娱乐。
搜索
您的当前位置:首页输入与输出支持

输入与输出支持

来源:二三娱乐

打印流 与

  如果要想通过程序实现内容的输出,核心的本质一定要依靠OutputStream类完成,但是OutputStream有一个很大的缺点:数据输出操作功能有限:public void write​(byte[] b) throws IOException,所有的数据一定要转为字节数组后才能输出,如果现在项目中需要输出long、double或者Date,这种情况下就必须将这些数据变为字节的形式来处理,这样的处理其实是非常麻烦的,所以在最初的开发中为了解决此类的重复操作,往往由开发者自行定义一些功能类已简化输出过程。

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("姓名:小强子");
        util.print("年龄:");
        util.print(78);
    }
}
class PrintUtil implements AutoCloseable {//实现数据常用的输出功能
    private OutputStream output;//不管现在如何进行输出操作,核心使用的就是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();
        }
    }
}

  在整个操作过程之中打印流的设计思想的本质在于:提高已有类的功能,例如:OutputStream是唯一可实现输出的操作标准类,所以应该以其为核心根本,但是这个类的输出的操作功能有限,所以不方便进行输出各个类型的数据,那么就为它做出了一层包装,所以此时采用的设计思想就是“装饰设计模式”。
  既然已经发现了原始的OutputStream功能的不足,所以为了解决输出问题,在java.io包中提供了打印流:PrintStream、PrintWriter。

  • PrintStream
public class PrintStream extends FilterOutputStream implements Appendable, Closeable

  构造方法:public PrintStream​(OutputStream out)

  • PrintWriter
public class PrintWriter extends Writer

  构造方法:public PrintWriter​(OutputStream out)

PrintStream与PrintWriter

  下面使用PrintWriter来实现数据的输出操作。
范例:数据输出

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("姓名:小强子");
        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类的处理操作会更加简单。以后只要是程序进行内容输出时全部使用打印流。

System类对IO的支持

  System类是一个系统类,而且是一个非常常用的系统类,而在该类中提供了和输入输出有关的三个常量:

  • 标准输出(显示器):public static final PrintStream out
  • 错误输出:public static final PrintStream err
  • 标准输入(键盘):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在进行System.err输出时会使用红色字体,System.out使用白色字体。
  最早设置两个输出的操作的目的: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类里面还提供了一个in的常量,而这个常量对应的是标准输入设备键盘的输入处理,可以实现键盘数据输入。
范例:实现键盘输入

import java.io.InputStream;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        InputStream in=System.in;//此时的输入流为键盘输入
        System.out.print("请输入信息:");
        byte[] data=new byte[1024];//长度限制
        int len=in.read(data);
        System.out.println("输入的内容为:"+new String(data,0,len));
        in.close();
        //请输入信息:asdasda
        //输入的内容为:asdasda
    }
}

  但是这样的键盘输入处理本身是有缺陷的:如果现在的长度不足,只能接收部分数据,所以这个输入就有可能需要进行重复的输入流数据接收,而且在接收时还会涉及到输入中文,如果对于中文处理不当,则也有可能造成乱码问题。

  BufferedReader类提供的是一个缓冲字符输入流的概念,也就是说利用BufferedReader类可以很好的解决输入流数据读取问题,这个类是在最初(JDK1.5之前,1.5后出了一个更很强大的类代替此类)的时候提供的最完善的数据输入的处理,之所以使用这个类来处理,是因为此类中提供有一个重要的方法:

  • 读取一行数据: public String readLine() throws IOException
BufferedReader

范例:实现键盘数据输入

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("请输入信息:");
        String msg=reader.readLine();
        System.out.println("输入的内容为:"+msg);
        reader.close();
        //请输入信息:123
        //输入的内容为:123
    }
}

  在以后的实际开发中经常会遇到输入数据的情况,所有输入数据的类型都是通过String描述的,那么这样就方便了接收者进行各种处理。
范例:接收整型输入并且验证

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("请输入您的年龄:");
        String msg=reader.readLine();
        if(msg.matches("\\d{1,3}")){
            int age=Integer.valueOf(msg);
            System.out.println("您输入的年龄:"+msg);
        }else{
            System.err.println("输入错误,你输入的内容:"+msg);
        }
        reader.close();
    }
}

  现在Java开发由键盘输入数据的情况并不多见,但是作为一些基础的逻辑训练还是可以使用键盘输入数据的,而键盘输入数据的标准做法(JDK1.5之前)就是上面的实现操作。实际开发中所有输入的数据全部为字符串,可以方便验证与进行复杂处理。

  java.util.Scanner是从JDK1.5之后追加的一个程序类,其主要的目的解决输入流的访问问题的,可以理解为BufferedReader的替代类,在Scanner类中有如下几种操作方法:

  • 构造方法:public Scanner​(InputStream source)
  • 判断是否有数据:public boolean hasNext()
  • 取出数据:public String next()
  • 设置分隔符:public Scanner useDelimiter​(String pattern)
    范例:使用Scanner实现键盘输入字符串
import java.util.Scanner;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的姓名:");
        if (sc.hasNext()) {
            System.out.println("您输入的姓名:" + sc.next());//换行不算输入
        } else {
            System.err.println("输入有误,未获取到内容");
        }
    }
}

范例:使用Scanner实现键盘数字输入

import java.util.Scanner;
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的年龄:");
        if (sc.hasNextInt()) {//判断是否有整数输入
            int age = sc.nextInt();//可以直接获取数字
            System.out.println("您输入的年龄:" + age);
        }else{
            System.err.println("输入有误,未获取到内容");
        }
    }
}

  使用Scanner输入数据还有一个最大的的特点是可以直接利用正则进行验证判断。
范例:输入一个人的生日

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("请输入您的生日:");
        if (sc.hasNext(birthdayRegex)) {
            System.out.println("您输入的生日:" + sc.next());//换行不算输入
        } else {
            System.err.println("输入有误,未获取到内容");
        }
    }
}

范例:使用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为换行符
        while (sc.hasNext()) {
            System.out.println(sc.next());
        }
    }
}

  现在可以发现Scanner的整体设计要好于BufferedReader,而且要比InputStream类读取更方便。在以后的开发中,如果程序需要输出数据,则要使用打印流,输入数据使用Scanner或BufferedReader。

Copyright © 2019- yule263.com 版权所有 湘ICP备2023023988号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务