接下来这篇博文介绍java另1种Stream, print 流.  亦有人称其为打印流.

介绍这个print流之前有必要明确两点:

1. print 流是输出流, 只能用于输出到外部设备不能用于输入.

2. print 流是包裹流(处理流), 必须包裹在另1个流之上.

一, 其他输出流介绍

要了解print流的由来, 有必要明白print流和其他输出流的区别.

在这里首先重新go through一次一起博文介绍过的若干常用的输出流.

1.1 Writer

Writer是1个流的上层抽象类,  我们常用的FileWriter, CharArrayWriter 都是继承自这个类.

利用writer的 各种重载的write()方法可以写入

1. 1个字符 write(int) //字符二进制数据存放在int类型中

2. 1个字符数组 write(char[])

3. 1个字符数组的一部分 write(char[],int,int)

4. 1个字符串 或者 一个字符串的一部分 write(String,0,len)

Wirter的优点就是方便地处理字符外部设备(例如文本文件) 但是不能处理二进制外部设备(类如mp3文件).

1.2 OutputStream

OutputStream也是1个上层抽象类, 相对于Writer,OutputStream一次只能写入1个字节, 而不是字符.

我们常用的 FileOutputStream, ByteArrayOutputStream 都是继承自这个流.

利用OutputStream 可以的write方法可以写入

1. 1个字节 write(int)

2. 1个字节数组 write(byte[])

3. 1个字节数组的一部分 write(byte[],int,int)

OutputStream的优点就是可以处理一切文件, 包括文本文件和二进制文件.

1.3 DataOutputStream

基本上所有作为原始流的输出流都是继承子上面的两个抽象类(Writer 和 OutputStream)

而这个DataOutputStream 则是1个继承自OutputStream的1个包裹流, 它必须包裹在1个OutputStream的原始流之上.

利用DataOutputSream, 可以写入

1. 1个字节 write(int)

2. 1个字节数组 write(byte[])

3. 1个字节数组的一部分 write(byte[],int,int)

前面这3个都是继承自OutputStream, 没什么特别. 关键是下面这个

所有基本类型的二进制代码.

例如:

4. 1个int类型的二进制数据 writeInt(int)

5. 1个foat类型的二进制数据 writeFloat(float)

....

简单地讲,

如果执行 DataOutputStream 的 writeInt(100) 就会把100的二进制代码 1100100, 也就是 00 00 00 64(16进制表示) 写入到外部设备. 共占4个字节

1.3.1 DataOuputStream 1个例子

这个例子步骤很简单.

就是利用DataOutputStream 往1个文件(/home/gateman/tmp/testStream1.txt) 写入1个int类型 值是: 1229935882.

然后查看这个文件的内容.

代码如下:

import java.io.*;public class DataStream2{public static void f(){try{g();}catch(IOException e){e.printStackTrace();}}public static void g() throws IOException{int i = 1229935882;File f = new File("/home/gateman/tmp/testStream1.txt");if (f.exists()){f.delete();}f.createNewFile();FileOutputStream fos = new FileOutputStream(f);DataOutputStream dos = new DataOutputStream(fos);dos.writeInt(i);dos.flush();dos.close();System.out.printf("done!!\n"); }
}

代码很容易读懂, 这里不解释了.

当执行完这代码后, 首先用cat命令来查看这个文件的内容

gateman@TPEOS Java_1 $ ant
Buildfile: /media/store1/Studies/Java/java_start/Java_1/build.xmlmain:[javac] /media/store1/Studies/Java/java_start/Java_1/build.xml:10: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds[java] done!!BUILD SUCCESSFUL
Total time: 0 seconds
gateman@TPEOS Java_1 $ cat /home/gateman/tmp/testStream1.txt
IOU

简单文件的内容不是 数字1229935882,  而是三个字母 "IOU".

为何呢?

原因就是DataOutputStream会将 int类型1229935882 转换成 2进制

用16进制来表示就是 49 4f 55 0a.

至于10进制如何转换成16进制这里就不深究了.

我们可以用xxd来查看1个文件的2进制(16进制)内容:

gateman@TPEOS Java_1 $ xxd -g 1 /home/gateman/tmp/testStream1.txt
0000000: 49 4f 55 0a                                      IOU.

可以见到.

0000000: 这些是文件头部信息.

内容就是

49 4f 55 0a

那么为何输出是IOU?

因为cat命令不是输出文件的2进制代码命令, 而是将其视为1个文本文件来输出.

那么就会利用ASCII码来对文件的2进制数据进行编码.

在ASCII表中

16进制 49 -> 10进制 73 -> 字符'I'

4f -> 79 -> O

55 -> 85 -> U

0a -> 10 -> 换行符

所以用cat转码后输出就是"IOU\n"了

当然, 如果利用一般的文本编辑器打开, 例如vi, gedit等打开这个文件, 显示的文件内容也是IOU哦.

二, Print流介绍

上面提过了, print流是输出流的一种, 它也继承自基本的抽象类OutputStream 或 Writer.

除了继承过来(实际上是重写)的基本的write()方法之外,  print 流更重要的是具有多种的重载的print(), printf() 和 println()方法.

这些print()方法能用于各种不同类型数据的格式话输出.

例如DataOutputStream的 writeInt(int)能往外部设备写入 int类型数值的二进制数据.

而print流的 print(int)则可以往外部设备写入 Int类型数值的格式化输出.

再简单地讲:

DataOutputStream的 writeFloat(8.8) 写入的是8.8这个数值的二进制编码.

而PrintStream(printWriter)的 print(8.8) 写入的是'8', '.', '8' 这个3个字符.

2.1 一个例子

这个例子用于和上面例子做个对比.

我们利用PrintStream, 同样往1个文件写入 1229935882 这个int类型数据, 然后查看文件的内容.

代码如下:

import java.io.*;public class PrintStream1{public static void f(){try{g();}catch(IOException e){e.printStackTrace();}}public static void g() throws IOException{int i = 1229935882;File f = new File("/home/gateman/tmp/testStream2.txt");if (f.exists()){f.delete();}f.createNewFile();FileOutputStream fos = new FileOutputStream(f);PrintStream ps = new PrintStream(fos);ps.print(i);ps.print('\n');ps.flush();ps.close();System.out.printf("done!!\n"); }
}

可见上面DataOutputStream的改动很小, 只是把DataOutputStream 改成 PrintStream

输出:

gateman@TPEOS Java_1 $ cat /home/gateman/tmp/testStream2.txt
1229935882
gateman@TPEOS Java_1 $

可见 被写入的外部文件中就只是 '1229935882\n' 这个几个字符了.

三, Print流分类

我们常说的print流有两个

其中1个就是上面例子中的PrintStream. 它继承自OutputStream

另1个就是PrintWriter就是 Writer.

3.1 PrintStream

PrintStream继承自OuputStream的子类FilterOutputStream

PrintStream的方法都不会抛出IOException异常, 而是使用另一种error handling机制.

PrintStream必须包裹在另1个OutputStream上使用.

PrintStream的println()方法会产生'\n'换行符.

3.2 PrintWriter

printWriter继承自Writer

具有与PrintStream一样的方法.

它的方法也不会抛出IOException.

PrintWriter既可以包裹在Writer原始流使用, 也可以包裹在另1个OutputStream上.

PrintWriter的println()方法会根据不同的操作系统产生对应的换行符, 例如在linux下换行符是'\n', 在windows下的换行符则是'\r\n'

3.3 PrintStream 和 PrintWriter的区别

它们两者的使用方法基本上可以一样的.

区别有两个

1. PrintWriter可以包裹在另1个Writer上使用, 也可以包裹在另1个OutputStream上使用, 而PrintStream只能包裹在另1个OutputStream上使用.

2. PrintWriter的println()方法跨平台性更加好.

四, 常用的Print流

看到了pint() println()这些方法是不是想起我们常用的输出字符到屏幕的命令 System.out.println().

的确, System.out就是java系统封装好的1个指向标准输出设备的静态print流.

实际上System这个类有3个静态流

其中两个是PrintStream, 分别是

System.out  标准输出流(PrintStream), 默认指向屏幕

System.err   标准错误输出流(PrintStream),默认指向屏幕

System.in    标准输出流(InputStream), 默认指向键盘

4.1 System.out

首先, 要明白, System是1个类, 而不是1个包.

System: System是Java内部的类, 它包含了许多常用的静态字段和静态方法, 它不能实例化.

out: 而out是System的1个静态属性, 它指向java系统封装好的指向标准输出设备的一个静态PrintStream(注意不是PrintWriter)

标准输出设备: 所谓的标准设备就是计算的屏幕. 但是这个标准输出设备可以被改变.

setOut(PrintStream out): 利用setOut()方法可以改变标准输出设备, 例如我们可以将标准输出设备设置为1个FileOutputStream, 那么以后我们执行System.out.println()方法时, 就不再把信息输出到屏幕, 而是输出到那个FileOutputStream, 也就是1个文件里了.

简单地讲, A是1个PrintStream, 执行System.set(A)后,  System.out就等于A!

例子:

import java.io.*;public class SystemOut1{public static void f(){try{g();}catch(IOException e){e.printStackTrace();}}public static void g() throws IOException{PrintStream screenOS = System.out;//marked downSystem.out.println("It will be printed to monitor!");File f = new File("/home/gateman/tmp/testStream3.txt");if (f.exists()){f.delete();}FileOutputStream fos = new FileOutputStream(f);PrintStream ps = new PrintStream(fos,true); // autoflush = true;// PrintStream ps = new PrintStream(f); //another constructor;System.setOut(ps);System.out.println("It will be printed to file!");System.setOut(screenOS);// set to default valueSystem.out.println("It will be printed to monitor again!");ps.close();}
}

上面代码执行了三次System.out.println()方法.

第1次: 因为System.out是指向标准输出设备(屏幕)的PrintStream. 所以第一句被输出到了屏幕.

第2次: 标准输出设备被System.setOut()方法改变成了1个指向文件的PrintStream. 所以第二句被输出到了文件.

第3次: 标准输出设备再次被修改为默认值, 所以第三句输出到了屏幕.

执行结果:

gateman@TPEOS Java_1 $ ant
Buildfile: /media/store1/Studies/Java/java_start/Java_1/build.xmlmain:[javac] /media/store1/Studies/Java/java_start/Java_1/build.xml:10: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds[javac] Compiling 1 source file to /media/store1/Studies/Java/java_start/Java_1/build/classes[java] It will be printed to monitor![java] It will be printed to monitor again!BUILD SUCCESSFUL
Total time: 1 second
gateman@TPEOS Java_1 $ cat /home/gateman/tmp/testStream3.txt
It will be printed to file!

4.2 System.err

System.err 也是1个静态PrintStream.

作为程序猿, 很多情况下需要处理程序的错误, 当错误发生时, 我们会把一些错误信息输出.

System.err 实际上就是1个指向标准错误输出设备的PrintStream.

所谓标准错误输出设备是什么? 默认也是屏幕, 但是很多情况下我们会修改其为1个专门存储错误信息的log文件.

有两个常用的方法会利用System.err

1个就是直接执行System.err的printf/print/println()方法.

另1个就是Exception的方法printStackTrace(); 这个方法实际上也是输出到标准错误输出设备.

同理, 我们也可以利用System.setErr()方法来改变标准错误输出设备的指向.

例子:

import java.io.*;public class SystemErr1{public static void f(){try{g();}catch(Exception e){e.printStackTrace();}}public static void h() throws IOException{throw new IOException("Shit !!! / by zero!");}public static void g() throws Exception{int i = 0;int j =0;File f = new File("/home/gateman/tmp/testStream4.txt");if (f.exists()){f.delete();}FileOutputStream fos = new FileOutputStream(f);PrintStream ps = new PrintStream(fos,true); // autoflush = true;// PrintStream ps = new PrintStream(f); //another constructor;try{j = 3 / i;  }catch(Exception e){System.err.println("this err msg will be printed to monitor!");e.printStackTrace();}System.setErr(ps);try{h(); }catch(Exception e){System.err.println("this err msg will be printed to file!");e.printStackTrace();}ps.close();}
}

上面的代码输出次错误信息.

第一次输出到屏幕

第二次输出到1个文件

执行结果:

gateman@TPEOS Java_1 $ ant
Buildfile: /media/store1/Studies/Java/java_start/Java_1/build.xmlmain:[javac] /media/store1/Studies/Java/java_start/Java_1/build.xml:10: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds[java] this err msg will be printed to monitor![java] java.lang.ArithmeticException: / by zero[java]     at Stream_kng.PrintStream_kng.SystemErr1.g(SystemErr1.java:33)[java]    at Stream_kng.PrintStream_kng.SystemErr1.f(SystemErr1.java:9)[java]     at Enter_1.main(Enter_1.java:95)[java]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[java]    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[java]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[java]  at java.lang.reflect.Method.invoke(Method.java:601)[java]   at org.apache.tools.ant.taskdefs.ExecuteJava.run(ExecuteJava.java:217)[java]    at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:152)[java]    at org.apache.tools.ant.taskdefs.Java.run(Java.java:771)[java]  at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:221)[java]  at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:135)[java]  at org.apache.tools.ant.taskdefs.Java.execute(Java.java:108)[java]  at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)[java]   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[java]    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[java]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[java]  at java.lang.reflect.Method.invoke(Method.java:601)[java]   at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)[java]    at org.apache.tools.ant.Task.perform(Task.java:348)[java]   at org.apache.tools.ant.Target.execute(Target.java:435)[java]   at org.apache.tools.ant.Target.performTasks(Target.java:456)[java]  at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)[java]   at org.apache.tools.ant.Project.executeTarget(Project.java:1364)[java]  at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)[java]    at org.apache.tools.ant.Project.executeTargets(Project.java:1248)[java]     at org.apache.tools.ant.Main.runBuild(Main.java:851)[java]  at org.apache.tools.ant.Main.startAnt(Main.java:235)[java]  at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)[java]    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)BUILD SUCCESSFUL
Total time: 0 seconds
gateman@TPEOS Java_1 $ cat /home/gateman/tmp/testStream4.txt
this err msg will be printed to file!
java.io.IOException: Shit !!! / by zero!at Stream_kng.PrintStream_kng.SystemErr1.h(SystemErr1.java:16)at Stream_kng.PrintStream_kng.SystemErr1.g(SystemErr1.java:42)at Stream_kng.PrintStream_kng.SystemErr1.f(SystemErr1.java:9)at Enter_1.main(Enter_1.java:95)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:601)at org.apache.tools.ant.taskdefs.ExecuteJava.run(ExecuteJava.java:217)at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:152)at org.apache.tools.ant.taskdefs.Java.run(Java.java:771)at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:221)at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:135)at org.apache.tools.ant.taskdefs.Java.execute(Java.java:108)at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:601)at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)at org.apache.tools.ant.Task.perform(Task.java:348)at org.apache.tools.ant.Target.execute(Target.java:435)at org.apache.tools.ant.Target.performTasks(Target.java:456)at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)at org.apache.tools.ant.Project.executeTarget(Project.java:1364)at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)at org.apache.tools.ant.Project.executeTargets(Project.java:1248)at org.apache.tools.ant.Main.runBuild(Main.java:851)at org.apache.tools.ant.Main.startAnt(Main.java:235)at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)at org.apache.to

4.2 标准输出和标准错误输出的重定向

在项目编程中, 有时我们需要把正常输出到1个文件, 错误输出到另外一个文件方便记录和以后查看, 这时我们可以利用System.setOut() 和 System.setErr()方法来改变输出的指向.

这个就是所谓的标准和标准错误的重定向输出了.

Java print流简介相关推荐

  1. Java IO流简介

    Java中的流是什么? java中的流是一个抽象的概念,在java的程序中需要把文件从一个设备传输到另一个设备上,这个设备可以是内存,程序,文件,网络.把在这些之间传输的叫做流.官方的解释:流是一组有 ...

  2. Java 转换流 简介

    在以前的博文也提过了, java的Stream根据传输的最小单位, 可以分为字符流和字节流. 字节流应用面更广,  而字符流在某些情况(例如文本处理)会更加方便. 而在编程中,  有时程序接收到的是一 ...

  3. Java 缓冲流简介及简单用法

    在java编程中, 我们有时会听到缓冲流和原始流等字眼. 其实在之前的博文中, 提到过流可以分为原始流和处理流. http://blog.csdn.net/nvd11/article/details/ ...

  4. java io字符流_Java IO流字符流简介及基本使用

    Java IO流字符流简介及常用字符流的基本使用 字符流分为输入字符流(Writer)和输出字符流(Reader),这两种字符流及其子类字符流都有自己专门的功能.在编码中我们常用的输出字符流有File ...

  5. java 8流自定义收集器_Java 8编写自定义收集器简介

    java 8流自定义收集器 Java 8引入了收集器的概念. 大多数时候,我们几乎不使用Collectors类中的工厂方法,例如collect(toList()) , toSet()或其他更有趣的方法 ...

  6. java IO流基础 万字详解(从拷贝文件到模拟上传头像)

    目录 一.前言: 二.IO流简介: 1.什么是IO流? 2.IO流能干什么? 3.IO流的分类: 4.IO流体系: 三.字符流读写文件: 1.普通字符流读取文件: 前言: ①以单个字符读取: 代码演示 ...

  7. 【Java】流式编程学习笔记

    文章目录 一.流简介 二.创建流 2.1 由值创建流:of 2.2 由列表创建流:stream 2.3 由 Builder 创建流:build 2.4 由文件生成流:lines 2.5 由函数生成流 ...

  8. Java IO流(详解)

    1. File 1. 创建 2. 操作 1. 获取文件信息 2. 目录创建/删除 2. IO流 1. FileInputStream 1. 简单使用 2. 读取中文 2. FileOutputStre ...

  9. Java stream流式计算详解

    Java stream流式计算详解 1. Stream概述 1.1 Stream简介 1.2 Stream分类 2. Stream操作 2.1 Stream创建 2.2 Stream无状态操作 2.3 ...

最新文章

  1. Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)
  2. Java并发编程——volatile
  3. 全球及中国4-氨基间甲酚行业应用需求与发展策略分析报告2022版
  4. 关于对下阶段工作的一些建议10.10
  5. linux下各种颜色文件的意义
  6. svn--Eclipse版本的安装步骤
  7. 爱立信发布体验版WebRTC移动浏览器…
  8. 计算机网络实验【常见网络测试命令的使用】
  9. stm32f10x系列.s汇编启动文件
  10. Python 图像处理 OpenCV (13): Scharr 算子和 LOG 算子边缘检测技术
  11. Beetl的基本用法
  12. 徐家骏:我在华为工作十年的感悟
  13. js 根据链接生成二维码
  14. 使用R语言 在rstudio中出现 列的数目比列的名字要多 的问题
  15. 中国版-IBM Bluemix初体验
  16. Java 之父高斯林加入亚马逊 AWS
  17. 又学到了一个重要的公式,点到直线的距离,欧耶,为自己鼓掌
  18. iOS获取图片的区域主色
  19. Python技术手册 · 函数的多返回值&文件操作
  20. FORMULA ONE RACES AHEAD (F1锦标赛全速前进)

热门文章

  1. [密码学] DES(二)
  2. buu [GKCTF2020]小学生的密码学
  3. Linux常用的基本命令vi、ps、kill(四)
  4. python_面向对象进阶之slots
  5. [Issue Fixed]-repo-error: .repo/manifests/: contains uncommitted changes
  6. linux kernel中__setup()函数介绍
  7. 第一次scrapy爬虫记录
  8. SEH反调试(SetUnhandledExceptionFilter)
  9. CVE-2021-33909:Linux本地权限提升漏洞
  10. ACM入门之【差分】