javaIO流(四)--输入与输出支持

一.打印流
  如果现在要想通过程序实现内容的输出,核心的本质一定要依靠OutputStream类来支持但是OutputStream类有一个最大的缺点,这个类的数据输出操作功能有限,所有的数据一定要转为字节数组后才可以进行才操作:public void write(byte b[]) throws IOException,假设说项目中可能输出的是long,double,date,在这样的情况下就必须将这些数据转变为字节的形式来进行处理,这样的处理一定是非常麻烦的.所以在开发之中最初的时候为了解决此类的重复操作,往往会由开发者自行定义一些功能类来简化输出操作:

1 class PrintUtil {    //实现一些常用数据的山输出
2     private OutputStream output;        //不管如何进行输出操作,核心就是OutputStream
3
4     public void print(String str) throws IOException {      //输出字符串
5         this.output.write(str.getBytes());
6     }
7 }

--在我们的输出过中,我们的输出操作不可能只会向文件,内存,管道中单一的进行输出,所针对的输出环境可能是非常多的,因此我们无法限定输出环境,因此如果我们在PrintUtil类中直接定义了OutputStream类的实例化对象,那么这个类所完成的代码就将造成严重的耦合(这个类只能对指定的类进行输出使用),既然OutputStream类有很多的子类可以被我们使用,最好的解决办法就是通过构造方法,外部传入OutputStream的对象,我们可以模仿java打印流的实现思路来完善我们的代码:

 1 class PrintUtil implements AutoCloseable {    //实现一些常用数据的山输出
 2     private OutputStream output;        //不管如何进行输出操作,核心就是OutputStream
 3
 4     public PrintUtil(OutputStream output) {
 5         this.output = output;
 6     }
 7
 8     public void print(long num) throws IOException {
 9         this.print(String.valueOf(num));
10     }
11
12     public void print(String str) throws IOException {      //输出字符串
13         this.output.write(str.getBytes());
14     }
15
16     public void println(long num) throws IOException {
17         this.println(String.valueOf(num));
18     }
19
20     public void println(String str) throws IOException {
21         this.print(str + "\r\n");
22     }
23
24     @Override
25     public void close() throws Exception {
26         output.close();
27     }
28 }
29
30 public class Demo {
31     public static void main(String[] args) throws Exception {
32         File file = new File("d:" + File.separator + "java_test" + File.separator + "demo01.txt");
33         PrintUtil printUtil = new PrintUtil(new FileOutputStream(file));
34         printUtil.println("第一次输出: 你好");
35         printUtil.println("第二此输出: 你也好");
36         printUtil.print(",你喜欢写代码吗?");
37         printUtil.print(123456);
38         printUtil.close();
39     }
40 }

--打开文件查看输出结果

第一次输出: 你好
第二此输出: 你也好
,你喜欢写代码吗?123456

--在整个的操作过程中,打印流的设计思想的本质在于提高已有类的功能,OutputStream类是唯一可以提供输出的操作标标准类,所以应该以其为核心根本,但是这个类输出的操作功能有限,所以不方便进行输出各个数据类型,那么就为他作出了一层包装.上述的代码设计思想那么我们就可以称其为"装饰设计模式".
--既然我们已经发现了原始的OutputStream功能的不足,java的设计者也一定可以发现这个问题,所以在java,io包中为我们提供了打印流:
  PrintStream(JDK1.0):  字节打印流

--可以发现在PrintStream的构造方法中又传递了OutputStream,这样的结构形式和代理模式是非常相似的,但是其主要的区别是:代理是围绕接口展开的,代理的时候调用的方法一定是接口中的方法而装饰设计模式中所使用的方法一定不是OutputStream中的方法,
  PrintWriter(JDK1.1):  字符打印流

--可以发现PrintWriter的构造方法中,除了可以接收OutputStream以外,还可以接收Writer等参数.
--范例:使用PrintWriter来实现数据的输出操作:

 1 public class PrintWriterDemo {
 2     public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
 3         File file = new File("d:" + File.separator + "java_test" + File.separator + "demo01.txt");
 4         PrintWriter printWriter = new PrintWriter(new FileOutputStream(file));
 5         printWriter.println("第一次输出: 你好");
 6         printWriter.println("第二此输出: 你也好");
 7         printWriter.print(",你喜欢写代码吗?");
 8         printWriter.print(123456);
 9         printWriter.close();
10     }
11 }

--PrintWriter在JDK1.5之后追加了格式化输出操作的支持:public PrintWriter printf(String format, Object ... args)

--范例:格式化输出

 1 public class PrintWriterDemo {
 2     public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
 3         File file = new File("d:" + File.separator + "java_test" + File.separator + "demo01.txt");
 4         PrintWriter printWriter = new PrintWriter(new FileOutputStream(file));
 5         String name = "张三";
 6         int age = 75;
 7         double money = 45612.5236856;
 8         printWriter.printf("姓名:%s,年龄:%d,收入:%9.2f", name, age, money);
 9         printWriter.close();
10     }
11 }

--打开文件查看输出结果

姓名:张三,年龄:75,收入: 45612.52

--相比直接使用OutputStream类,那么使用PrintWriter,PrintStream类的处理操作会更加的简单,因此只要是程序进行内容输出的时候应全部使用打印流.

二.System类的IO的支持
  System类是一个系统类,而且是一直都在被使用的系统类,而且在这个类中定义有三个常量:
--System类中的静态常量:
  标准输出(显示器):public final static PrintStream out
  错误输出:public final static PrintStream err
  标准输入(键盘):public final static InputStream in
--范例:查看标准输出与错误输出

 1 public class OutAndErrorDemo {
 2     public static void main(String[] args) {
 3         try {
 4             Integer.valueOf("a");
 5         }catch (Exception e){
 6             System.out.println(e);
 7             System.err.println(e);
 8         }
 9     }
10 }

--运行结果

java.lang.NumberFormatException: For input string: "a"
java.lang.NumberFormatException: For input string: "a"

Process finished with exit code 0

---我们所使用的编译器可以为我们进行一些细微的差别优化(颜色),如果使用命令行去编译执行我们的java代码,那么我们将无法区别两者输出显示的差别
--System.out以及System.err是同一种类型的,最早设置两个输出的操作是有目的的:System.out是输出那些希望用户可以看见的信息,而System.err是输出那些不希望用户看见的信息.如果有需要,现在也可以修改输出的位置:
--修改out的输出位置:

 1 public class OutAndErrorDemo {
 2     public static void main(String[] args) throws FileNotFoundException {
 3         File file = new File("d:" + File.separator + "java_test" + File.separator + "demo02.txt");
 4         System.setErr(new PrintStream(
 5                 new FileOutputStream(file)));
 6         try {
 7             Integer.valueOf("a");
 8         }catch (Exception e){
 9             System.out.println(e);
10             System.err.println(e);
11         }
12     }
13 }

--在System类中还提供有一个in的常量,而这个常量对应的是标准输入设备键盘的输出处理,可以实现键盘的数据输入:

1 public class SystemInDemo {
2     public static void main(String[] args) throws IOException {
3         InputStream input = System.in;      //此时的输入流为键盘输入
4         System.out.println("请输入信息:");
5         byte[] data = new byte[1024];
6         int len = input.read(data);
7         System.out.println("输入内容为: " + new String(data,0,len));
8     }
9 }

--执行结果

请输入信息:
你好
输入内容为: 你好

Process finished with exit code 0

--这样的键盘输入处理,本身是有缺陷的,如果我们接受的数组长度不足,那么只能接受部分数据,所以输入有可能需要进行重复的输入流数据接受,而且在接收的时候,还有可能会牵扯到输入中文的情况,如果我们对中文的处理不当,则有可能造成乱码问题.

三.BufferedReader缓冲流

  BufferedReader类提供的是一个缓冲字符输入流的概念,也就是说利用BufferedReader类可以很好的解决输入流数据的读取问题,实际上java.io所提供的Buffer类还有BufferedOutputStream,BufferedInputStream,BufferedWriter等类,但是BufferedReader这个类是在最初的时候提供的最完善的数据输入的处理(JDK1.5),在之后则出了一个功能更为强大的类.之所以我们使用BufferedReader类来处理,因为该方法中有一个重要的方法:public String readLine() throws IOExpection;以换行符为分割点读取一行数据
--BufferedReader类继承结构分析:

--要先使用此类完成一个键盘输入事件的处理,我们需要知道对于键盘输入事件,java所提供的方法就是System.in(InputStream),而BufferedReader的构造器所接受的是Reader类,因此我们需要使用到转换流:InputStreamReader:

--范例:实现键盘数据输入

1 public class BufferedReaderDemo {
2     public static void main(String[] args) throws IOException {
3         BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
4         System.out.println("请输入信息:");
5         String msg = input.readLine();      //接收输入信息
6         System.out.println("输入内容为: " + msg);
7     }
8 }

--运行结果

请输入信息:
hello你好
输入内容为: hello你好

Process finished with exit code 0

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

 1 public class BufferedReaderDemo {
 2     public static void main(String[] args) throws IOException {
 3         BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
 4         System.out.println("请输入您的年龄:");
 5         String msg = "";      //接收输入信息
 6         while (!(msg = input.readLine()).matches("\\d+")) {
 7             System.out.println("您输入的数据有误,请重新输入: ");
 8         }
 9         System.out.println("输入的年龄为: " + msg);
10     }
11 }

--运行结果

请输入您的年龄:
sad
您输入的数据有误,请重新输入:
ss
您输入的数据有误,请重新输入:
56
输入的年龄为: 56

Process finished with exit code 0

--对于现代的java开发,由键盘输入数据的情况并不多,但是作为一些基础的逻辑训练,还是可以使用键盘输入数据的,而最早的键盘输入数据的实现做法就是如上的操作

四.Scanner类
  Scanner类是在java.util下在JDK1.5之后追加的程序类,其主要的目的是为了解决输入流的访问问题的,可以理解为BufferedReader的替代产品类,此类存在如下构造方法:Scanner(InputStream source)
--常用方法:
  判断是否有数据: public boolean hasNext();
  取出数据:  public String next();
  设置分隔符:public Scanner useDelimiter(String pattern)
--范例:使用Scanner实现键盘数据输入:

 1 public class ScannerDemo {
 2     public static void main(String[] args) {
 3         Scanner scanner = new Scanner(System.in);
 4         System.out.println("请输入年龄:");
 5         if(scanner.hasNextInt()){       //是否有整数输入
 6             int age = scanner.nextInt();        //直接接收数据
 7             System.out.println("您的年龄: " + age);
 8         }else {
 9             System.out.println("您输入的不对啊");
10         }
11         scanner.close();
12     }
13 }

--运行结果

请输入年龄:
55
您的年龄: 55

Process finished with exit code 0

--我们可以发现Scanner的处理会更加的简单,使用Scanner输入数据,最大的特点是直接可以结合正则使用进行自定义输入验证:

 1 public class ScannerDemo {
 2     public static void main(String[] args) throws ParseException {
 3         Scanner scanner = new Scanner(System.in);
 4         System.out.println("请输入您的生日:");
 5         if (!scanner.hasNext("\\d{4}-\\d{2}-\\d{2}")) {
 6             System.out.println("您的输入有误");
 7         }else {
 8             String birthday = scanner.next();
 9             System.out.println("您的生日为: " + new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
10         }
11         scanner.close();
12     }
13 }

--运行结果

请输入您的生日:
1888-08-05
您的生日为: Sun Aug 05 00:00:00 CST 1888

Process finished with exit code 0

--可以发现Scanner的整体设计要好于BufferReader,而且要比直接使用InputStream类要强大的,读取更加方便.例如现在要读取一个文本文件中的所有内容信息,如果采用的
是InputStream,那么必须采用内存输出流进行临时数据的保存,随后还需要判断读取的内容是否是换行,再进行输出,如果使用Scanner读取则结果如下:

 1 public class ScannerReadFileDemo {
 2     public static void main(String[] args) throws FileNotFoundException {
 3         File file = new File("d:" + File.separator + "java_test" + File.separator + "demo01.txt");
 4         Scanner scanner = new Scanner(file);
 5         scanner.useDelimiter("\n"); //设置读取分割符
 6         while (scanner.hasNext()){
 7             System.out.println(scanner.next());
 8         }
 9         scanner.close();
10     }
11 }

--运行结果

1 姓名:张三,年龄:75,收入: 45612.52
2 姓名:张三,年龄:75,收入: 45612.52
3 大叔关于不压缩大本营
4 1561441852
5 水水水水水水水水水水水水水水
6
7 Process finished with exit code 0

--在此我们可以进行如下总结:如果程序需要输出数据一定使用打印流,输入数据使用Scanner(BufferReader)

原文地址:https://www.cnblogs.com/skykuqi/p/11415576.html

时间: 2024-10-24 16:00:30

javaIO流(四)--输入与输出支持的相关文章

字符流的输入和输出

什么是流? 在java中对数据的操作,我们成为流 那么流的表现形式是什么呢? 我们最直观的感受就是文字的输入和输出,那么必然与文件相关联. 为什么出现字符流? 因为java字符流集成了编码集,你能够指定用什么编码来解读文字,这和各国不同不同编码集有关系,我们在java中指定编码,这样我们可以识别文字. FileReader FileWriter FileReader   读的两种方式 1.读入一个字符 import java.io.*; class FileReaderDemo { public

第十八章:输入与输出支持

打印流 如果现在要想通过程序实现内容的输出,核心的本质一定要依靠OutputStream类完成,但是OutputStream类有一个最大的缺点,这类的数据输出操作功能有限public void write(byte[] b) throws IOException,所有的数据一定要转为字节数组后才可以输出,于是假设说现在你的项目里面可能输出的是long,double,Date,在这样的情况下就必须将这些数据变为字节的形式来处理,这样的处理一定是非常麻烦的,所以在开发之中最初的时候为了解决此类的重复

perl学习笔记四——输入与输出

读取标准输入 用<STDIN>进行标准输入:chomp($line=<STDIN>); 如果读到文件尾,行输入操作符就会返回undef.便可利用这一性质跳出循环. while(defined ($line=<STDIN>)){ print "I saw $line"; } 简写为: while(<STDIN>){ print "I saw $_ ."; } 注意:这个简写只在最早的写法中才能正常运行,如果将行输入操作符

java _io_字符缓冲流的输入、输出

新增方法:输入:BufferedReader breader=new BufferedReader(Reader reader);.readLine()读取一行内容,返回字符串输出:BufferedWriter bwriter=new BufferedWirter(Writer writer);.newLine() 写入一个换行符 输入:File f =new File("C:\Users\10853\eclipse-workspace\hell\src\hell\abc");Buff

Java输入及输出处理(I/O流)

IO流的分类: 按流向分类:输入流.输出流按操作对象分类: 字节流.字符流按功能分类: 节点流.处理流 Input 输入Output 输出Java.io.File类,文件输入输出类 字节流和字符流: 1,字节流InputStream(读),OutputStream(写).2,字符流:Reader(读),Writer(写).基本的读写操作方式:因为数据通常都以文件形式存在.所以就要找到 IO 体系中可以用于操作文件的流对象.通过名称可以更容易获取该对象.因为 IO 体系中的子类名后缀绝大部分是父类

黑马程序员——JAVAIO流学习总结

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- www.itheima.com JAVA IO流类图结构: 显而易见了,IO流就是这个.下面我们来做些解释性的分析: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作. IO流的分类 根据处理数据类型的不同分为:字符流和字节流 根据数据流向不同分为:输

Java学习笔记—第十章 数据输入与输出

第十章  数据输入与输出 输入流与输出流: (1)输入流:以程序为基准,向程序中输入数据的流定义为输入流.从输入流向程序中输入数据称为读数据(read). (2)输出流:以程序为基准,从程序输出数据的流称为输出流.从程序中将数据输出到输出流称为写数据(write). 字节流和字符流 (1)字节流:按照字节的形式读/写数据.Java中抽象类InputStream和OutputStream及其派生子类用来处理字节流的输入和输出. (2)字符流:按照字符的形式读/写数据.Java中抽象类Reader和

输入和输出--IO流

JavaIO流 首先要理解这个"流"(stream)字:Java把不同的输入,输出源抽象成为流,通过流的方式允许Java程序使用相同的方式来访问不同的输入,输出源.把这里的"流"简单的理解成从起源到接受的有序数据就好了. IO流的分类: 一共有3种分类方式: 1,按流向分: 输入流:输出流 2,按处理的单位: 字节流(8 位的字节):字符流(16 位的字节) 3,按流的角色: 节点流:可以从一个特定的 IO 设备读/写数据的流 处理流:对一个已存在的流进行连接和封装

1.java.io包中定义了多个流类型来实现输入和输出功能,

1.java.io包中定义了多个流类型来实现输入和输出功能,可以从不同的角度对其进行分 类,按功能分为:(C),如果为读取的内容进行处理后再输出,需要使用下列哪种流?(G)   A.输入流和输出流 B.字节流和字符流 C.节点流和处理流   D.File stream E.Pipe stream F.Random stream G.Filter stream