zoukankan      html  css  js  c++  java
  • System类对IO的支持

    系统输出

      学完了PrintStream PrintWriter之后我们会发现里面方法很熟悉,例如:print() println() 实际上在之前使用的系统输出就利用了IO流模式完成的,在System类中定义有三个操作的常量:

        标准输出(显示器):public static final PrintStream out

        错误输出:public static final PrintStream err

        标准输入(键盘):public static final InputStream in

      原来之前使用的System.out.println()一直都属于IO的操作范畴。

    系统输出

      系统输出有两个常量:out err 而且这两个常量所表示的都是PrintStream类的对象,从Java的设计本质上来讲,这样的两种输出有以下的设计目的:out输出的是希望用户可以看见内容,err是希望输出用户不能看见的内容。

      这两种输出在实际的开发之中都没用。

     1 package cn.Tony.demo;
     2 
     3 public class TestDemo{
     4     public static void main(String[] args) throws Exception {
     5         try {
     6             Integer.parseInt("abc");
     7         }catch(Exception e) {
     8             System.err.println(e);
     9             System.out.println(e);
    10         }
    11         
    12     }
    13 }

      System.err也只是作为一个保留的属性提供存在。System.out属于PrintStream,属于OutputStream

    范例:

     1 package cn.Tony.demo;
     2 
     3 import java.io.OutputStream;
     4 
     5 public class TestDemo{
     6     public static void main(String[] args) throws Exception {
     7         OutputStream out=System.out;
     8         out.write("世界和平".getBytes());
     9     }
    10 }

      抽象类不同的子类针对同一方法有不同的实现,用户调用的时候的核心参考的就是OutputStream。

    系统输入 in

      System.in对于的类型是InputStream,而这种的输入流指的是由用户通过键盘进行输入(用户输入),java本身并没有这种直接的用户输入处理,如果要想实现这种输入处理必须用java.io的模式完成

    范例:利用InputStream

     1 package cn.Tony.demo;
     2 
     3 import java.io.InputStream;
     4 
     5 public class TestDemo{
     6     public static void main(String[] args) throws Exception {
     7         InputStream input=System.in;//为父类实例化
     8         byte data[]=new byte[1024];//开辟一个空间
     9         System.out.println("请输入信息:");
    10         int temp=input.read(data);//数据读取到字节数组中
    11         System.out.println("【ECHO】输入内容:"+new String(data,0,temp));
    12         
    13     }
    14 }

      现在发现当用户输入数据的时候需要暂停执行,也就是说程序进入到阻塞状态,直到用户输入完成(按下回车),那么才能向下执行,但是以上的程序本身有一个致命的问题,那么核心点就在于:要开辟的字节数组的长度是固定的,输入内容超过了该长度。如果开辟的量超过长度,只能接受部分数据,保存内存流,

     1 package cn.Tony.demo;
     2 
     3 import java.io.ByteArrayOutputStream;
     4 import java.io.InputStream;
     5 
     6 public class TestDemo{
     7     public static void main(String[] args) throws Exception {
     8         InputStream input=System.in;//为父类实例化
     9         ByteArrayOutputStream bos=new ByteArrayOutputStream();
    10         byte data[]=new byte[1024];//开辟一个空间
    11         System.out.println("请输入信息:");
    12         int temp=0;
    13         while((temp= input.read(data))!=-1) {
    14             //这里面需要由用户自己来处理换行的问题,因为换行不属于文件结束,所有内容不是-1
    15             bos.write(data,0,temp);
    16             if(temp<data.length) {
    17                 break;
    18             }
    19         }
    20         System.out.println("【ECHO】输入内容:"+new String(bos.toByteArray()));
    21         bos.close();
    22         input.close();
    23     }
    24 }

      虽然实现了键盘输入数据的功能,不过整体逻辑混乱,也就是说java本身所提供的System.in该操作不好用

     1 package cn.Tony.demo;
     2 import java.io.InputStream;
     3 public class TestDemo{
     4     public static void main(String[] args) throws Exception {
     5         InputStream input=System.in;//为父类实例化
     6         StringBuffer buf=new StringBuffer();
     7         System.out.println("请输入信息:");
     8         int temp=0; 
     9         while((temp= input.read())!=-1) {
    10             if(temp=='
    ') {
    11                 break;
    12             }
    13             buf.append((char)temp);
    14         }
    15         System.out.println("【ECHO】输入内容:"+buf);
    16         input.close();
    17     }
    18 }

      通过以上的比较可以感受到System.in的支持度原本不高,对于英文的操作该勉强可以使用,所以要中文,就必须结合内存流来完成,所以复杂度 是很高的,如果开发都这么写,就非常麻烦了

    总结:

      如果要想在IO中进行中文的处理,那么最好的做法是将所有输入的数据保存在一起再处理,这样才可以保证出现乱发,

      BufferedReader类属于一个缓冲的输入流,字符流的操作对象,但是必须清楚一点,对于缓冲流在java.io中定义有两类:字节缓冲流(BufferedInputStream),字符缓冲流(BufferedReader)。

      之所以选择BufferedReader类操作是因为在此类中提供的readLine()方法,这个方法可以直接读取一行数据(以回车为换行符)

        读取一行:public String readLine()throws IOException

      但是如果要想去使用BufferedReader类有一个问题需要注意了,来观察一下BufferdReader

    范例;利用BufferedReader实现键盘输入

     1 package cn.Tony.demo;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.InputStreamReader;
     5 
     6 public class TestDemo{
     7     public static void main(String[] args) throws Exception {
     8         BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
     9         System.out.println("请输入信息:");
    10         //默认的换行模式是BufferedReader最大缺点,如果不是因为此缺点,该类还好继续使用
    11         String str=buf.readLine();//接受输入信息,默认用回车换行
    12         System.out.println(str);
    13     }
    14 } 

      使用以上的形式实现的键盘输入还有一个最大的特点 ,由于接受的数据类型为String,那么也就证明可以使用正则判断。利用String类的各种操作进行处理,还可以变为各种常用的数据类型,

     1 package cn.Tony.demo;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.InputStreamReader;
     5 
     6 public class TestDemo{
     7     public static void main(String[] args) throws Exception {
     8         BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
     9         System.out.println("请输入信息:");
    10         //默认的换行模式是BufferedReader最大缺点,如果不是因为此缺点,该类还好继续使用
    11         String str=buf.readLine();//接受输入信息,默认用回车换行
    12         if(str.matches("\d{1,3}")) {
    13             System.out.println("【ECHO】输入信息为:"+Integer.parseInt(str));
    14         }else {
    15             System.out.println("输入的数据有错误");
    16         }
    17     }
    18 } 

      在很多的开发中依然可能会发现有BufferedReader类的身影,但是这个类随着时间的偏移,基本上使用的频率已经很低了。已经被新的类Scanner所取代了,

    总结

      BufferedReader类读取数据很方便(readLin)。

    Scanner

      打印流解决的是OutputStream缺陷,BufferedRead解决的是InputStream的缺陷,而java.Util.Scanner解决的是BufferedReader类的一个缺陷。

      Scanner是一个专门进行输入流处理的程序类,利用这个类可以方便处理数据类型。同时也可以直接结合正则表达式进行各项处理。在这个类中关注一下:

        判断是否有指定类型的数据:public boolean hasNextXxx()

        取得指定类型的数据:public 数据 nextXxx()

        定义分隔符:public Scanner useDelimiter(Pattern pattern)

        构造方法:public Scanner(InputStream source)

    范例:使用Scanner实现数据的输入

     1 package cn.Tony.demo;
     2 
     3 import java.util.Scanner;
     4 
     5 public class TestDemo{
     6     public static void main(String[] args) throws Exception {
     7         Scanner scan=new Scanner(System.in);
     8         System.out.println("请输入数据:");
     9         if(scan.hasNext()) {//现在有输入内容,不判断空字符串
    10             System.out.println("【ECHO】输入内容为:"+scan.next());
    11         }
    12         scan.close();
    13     }
    14 }

      使用Scanner输入还可以接收各种数据类型

    范例:

     1 package cn.Tony.demo;
     2 
     3 import java.util.Scanner;
     4 
     5 public class TestDemo{
     6     public static void main(String[] args) throws Exception {
     7         Scanner scan=new Scanner(System.in);
     8         System.out.println("请输入数据:");
     9         if(scan.hasNextInt()) {//现在有输入内容,不判断空字符串
    10             int age=scan.nextInt();
    11             System.out.println("【ECHO】输入内容为:"+age);
    12         }else{
    13             System.out.println("ERROR:输入不是数字");
    14         }
    15         scan.close();
    16     }
    17 } 

      最为重要的文图它可以对接收的数据类型使用正则表达式进行判断。

    范例:利用正则进行判断

     1 package cn.Tony.demo;
     2 
     3 import java.util.Scanner;
     4 
     5 public class TestDemo{
     6     public static void main(String[] args) throws Exception {
     7         Scanner scan=new Scanner(System.in);
     8         System.out.println("请输入数据:");
     9         if(scan.hasNext("\d{4}-\d{2}-\d{2}")) {
    10             String birthday=scan.next();
    11             System.out.println("生日:"+birthday);
    12         }else {
    13             System.out.println("错误");
    14         }
    15         scan.close();
    16     }
    17 } 

      但是以上的操作在开发中不会出现,

      使用Scanner本身能接收的是一个InputStream类的对象,例如:文件输入流。

     1 package cn.Tony.demo;
     2 import java.io.File;
     3 import java.io.FileInputStream;
     4 import java.util.Scanner;
     5 public class TestDemo{
     6     public static void main(String[] args) throws Exception {
     7         Scanner scan=new Scanner(new FileInputStream(new File("D:"+File.separator+"IO"+File.separator+"data.txt")));
     8         scan.useDelimiter(":");
     9         while(scan.hasNext()) {
    10             System.out.println(scan.next());
    11         }
    12         scan.close();
    13     }
    14 } 

      Scanner实际上完美的替代了BufferedReader,更好的实现了InputStream操作。

    总结:

      以后除了二进制的文件拷贝处理之外,那么只要是针对于程序的信息输出都是用打印流。信息输入都使用Scanner

  • 相关阅读:
    docker中centos7安装ssh服务
    redis加入systemctl服务
    elasticsearch设置执行脚本并添加开机启动 (转)
    CentOS7使用firewalld打开关闭防火墙与端口
    腾讯地图JSAPI开发demo 定位,查询
    C# 开发AliYun(阿里云) 小蜜调用接口代码
    VSCode 开发Core教程
    Rabbit原理理解
    Exceptionless 本地部署
    Visual Studio 2019 自带混淆工具DotFuscator不需要去网络下载
  • 原文地址:https://www.cnblogs.com/Tony98/p/10542108.html
Copyright © 2011-2022 走看看