• 第十三章 使用Scanner扫描器比使用io流更方便?


    使用Scanner扫描器比使用io流更方便?

    使用流读取/写入文件是我最常用的处理方式,今天又新学习了一种使用扫描【Scanner】输入的方法。

    对于读取一行文本,对其进行分词【Scanner分词定界符了解更多】,下面这种方式比较麻烦:

    1 package 字符串;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.IOException;
     5 import java.io.StringReader;
     6 import java.util.Scanner;
     7 
     8 /**
     9  * 扫描输入与使用流读入对比
    10  * 
    11  * 
    12  * @author admin
    13  *
    14  */
    15 public class Scan {
    16     
    17     public static final String STR = "Sir Robin of Camelot
    22 1.61803  0.897";
    18     
    19     public static void main(String[] args) {
    20         io();
    21     }
    22 
    23     public static void io() {
    24         BufferedReader br = new BufferedReader(new StringReader("Sir Robin of Camelot
    22 1.61803  0.897"));
    25         try {
    26             //读入一行
    27             String name = br.readLine();
    28             System.out.println(name);
    29             
    30             //只能一行一行读入,然后再对一行中的数据进行处理
    31             String str = br.readLine().replaceAll(" +"," ");
    32             System.out.println(str);
    33             
    34             String[] split = str.split(" ");
    35             System.out.println(Integer.parseInt(split[0]));
    36             System.out.println(Double.parseDouble(split[1]));
    37             System.out.println(Double.parseDouble(split[2]));
    38             
    39         } catch (IOException e) {
    40             e.printStackTrace();
    41         }finally {
    42             try {
    43                 if(br!=null) {
    44                     br.close();
    45                 }
    46             }catch(IOException e) {
    47                 e.printStackTrace();
    48             }
    49         }
    50     }
    51 
    52 }

    控制台:

    Sir Robin of Camelot
    22 1.61803 0.897
    22
    1.61803
    0.897

    用上面这种方式,你可以看到,如果你想提取一行里的数据,只能使用一些小手段,先将他们分割,然后再取出,在转为你想要的类型,操作代码比较繁琐,而且你还要去处理异常。

    使用Scanner【java.util.Scanner】扫描器就方便了许多,它的优点看下面代码分析:

     1 package 字符串;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.IOException;
     5 import java.io.StringReader;
     6 import java.util.Scanner;
     7 
     8 /**
     9  * 扫描输入与使用流读入对比
    10  * 
    11  * 
    12  * @author admin
    13  *
    14  */
    15 public class Scan {
    16     
    17     public static final String STR = "Sir Robin of Camelot
    22 1.61803  0.897";
    18     
    19     public static void main(String[] args) {
    20         scan();
    21         backUpRead();
    22     }
    23     
    24     
    25     @SuppressWarnings("resource")
    26     public static void scan() {
    27         Scanner scanner = new Scanner(Scan.STR);
    28         
    29         //nextLine()读取下一行的内容,并且指针向下移动一行
    30         System.out.println(scanner.nextLine());//只认换行符,不认我直接换行
    31 
    32         //nextInt()/nextDouble()指针不会在向下移动,而是水平移动。
    33         System.out.println(scanner.nextInt());
    34         System.out.println(scanner.nextDouble());
    35         System.out.println(scanner.nextDouble());
    36         
    37         
    38         //当找不到本行内下一个值时会抛出异常。找不到下一行时也会抛出异常
    39         //System.out.println(scanner.nextDouble());
    40         //System.out.println(scanner.nextLine());
    41         
    42         //Scanner有一个假设,在输入结束时会抛出IOException,所以Sanner会把IOExecption吞掉
    43         System.out.println(scanner.ioException());
    44     }
    45     
    46     public static void backUpRead() {
    47         Scanner scanner = new Scanner(System.in);
    48         
    49         System.out.println("你叫什么名字呀?");
    50         System.out.println(scanner.next());
    51         
    52         System.out.println("你家住哪呀?");
    53         System.out.println(scanner.next());
    54         
    55     }
    56 
    57 }

    控制台:

    Sir Robin of Camelot
    22
    1.61803
    0.897
    null
    你叫什么名字呀?
    毛毛
    毛毛
    你家住哪呀?
    上海
    上海

    Scanner有许多重载的构造器,所有你想使用的流【文件流,缓存流等等】【这里的流指的是输入流】,都可以在最外层套上扫描器。这样你不仅可以方便的使用readLine()方法,而且对于分词的处理更加方便,从上面代码中也可以看到在使用读取下一行方法next()时以及读取本行内数据nextInt()/nextDouble等方法时并不需要你去写try-catch块。因为Scanner有一个假设,在输入结束时会抛出IOException,所以Scanner会把IOException吞掉【你可以通过ioException()方法,找到最近发生的异常,在必要时刻你可以去检查它】,这样你就没必要每次都去写try-catch块了。想关闭流的话,你可以专门写一个方法,将流对象传入,在这个关闭流对象的方法里将流关闭。

    在输入结束时吞掉异常:它并不会吞掉你自己操作导致的异常,就像上面带代码39或40行那样,没有经过hasNextDouble()方法的判断,就直接使用,导致抛出NoSuchElemetmentException异常,它并不会帮你吞掉,所以最好的办法是先判断,在使用。只要不是你非法操作导致的问题,Scanner还是很乐意为您效力的。

    Scanner套接字节流或字符流:

    字节流的套接:在Scanner的构造方法中Scanner(InputStream source),InputStream只要经过适当的套接,总能获得你想要的流接口。

    字符流的套接:Scanner(Readable source),你需要使用Java SE5中新加入的一个接口Readable,该接口表示“具有read()方法的某种东西”,查看Readable接口的API你可以发现你想要的带有Reader的类基本都在其中。

    附:

    用正则表达式扫描【不允许你的正则表达式中出现定界符,Scanner默认的定界符也不能出现】:

     1 package 字符串;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.IOException;
     5 import java.io.StringReader;
     6 import java.util.Scanner;
     7 import java.util.regex.MatchResult;
     8 import java.util.regex.Matcher;
     9 import java.util.regex.Pattern;
    10 
    11 /**
    12  * 
    13  * @author admin
    14  *
    15  */
    16 public class Scan {
    17     
    18     public static void main(String[] args) {
    19         scanByRegex();
    20     }
    21     
    22     public static void scanByRegex() {
    23         String str = "58.27.90.129@02/10/2005
    "+
    24                     "67.12.20.234@24/07/2006
    ";
    25         Scanner sc = new Scanner(str);
    26         Pattern pattern = Pattern.compile("(\d+[.]\d+[.]\d+[.]\d+)@(\d{2}/\d{2}/\d{4})");
    27         while(sc.hasNext(pattern)) {
    28             System.out.println(sc.next(pattern));
    29             MatchResult match = sc.match();
    30             String ip = match.group(1);
    31             String date = match.group(2);
    32             System.out.format("Thread on %s from %s
    ", date,ip);
    33         }
    34     }
    35 
    36 }

    控制台:

    58.27.90.129@02/10/2005
    Thread on 02/10/2005 from 58.27.90.129
    67.12.20.234@24/07/2006
    Thread on 24/07/2006 from 67.12.20.234

     

    前进时,请别遗忘了身后的脚印。
  • 相关阅读:
    DS博客作业06——图
    DS博客作业05——树
    DS博客作业03——栈和队列
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实验
    C语言课设——电影院选票系统
    C语言博客作业06——结构体&文件
    C语言博客作业05——指针
    DS博客作业08--课程总结
    DS博客作业07--查找
  • 原文地址:https://www.cnblogs.com/liudaihuablogs/p/9303277.html
Copyright © 2020-2023  润新知