一、字节流分类概括

-->1、ByteArrayInputStream /ByteArrayOutputStream(数组字节输入输出)

       InputStream/OutputStream            -->2、FileInputStream/FileOutputStream(文件字节输入输出流【参考19.03.30文章】)

(四大抽象类之二,与Reader/Writer平辈)   -->3、ObjectInputStream/ObjectOutputStream(对象字节输入输出流)

-->4、FilterInputStream/FilterOutputStream(加装饰器的输入/输出流)-----》》

----------------》》4-1:BufferedInputStream/BufferedOutputStream(带缓冲区的字节流)  【参考19.3.30文章】

----------------》》4-2:DataInputStream/DataOutputStream(数据输入/输出流)

----------------》》4-3:【独有】PrintStream打印输出流、处理流

1、ByteArrayInputStream /ByteArrayOutputStream(数组字节输入输出)

 /**学习 1、文件数组字节流 (InputStream/OutputStream的亲儿子)
* ByteArrayInputStream /ByteArrayOutputStream(文件数组字节输入输出)与FileInputStream/FileOutputStream平辈
* 以前源头:本地电脑硬盘文件<-----操作系统----->Java虚拟机 。以前的FileInputStream/FileOutputStream的用法
* 所以每次都要通知操作系统释放内存
* 现在源头:本地电脑的另外一块内存/网络上的一块内存/远程服务器的一块内存 ,看成一块字节数组,所以可以让Java虚拟机直接访问
* 与操作系统无关,使用完后由垃圾回收机制管理,不用释放内存。风格统一,可以释放内存,是实际没作用。
* 1、任何东西都可以转成字节数组 2、字节数组不要太大
*
* 写数据:ByteArrayOutputStream
* 不需要指定文件目的地,这点与FileOutputStream(如需要自己指定个"dest.txt")不同,因为是内存写的,大小不好管理
* 可以不用释放操作
*
*/
package cn.sxt.test; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; public class Test_0401_ArrayStream {
public static void main(String[] args) throws IOException {
//1、创建源 字符串,编码成字节数组
byte[] src="I am angry,Are you OK!".getBytes();
//2、选择流
ByteArrayInputStream bStream=new ByteArrayInputStream(src);
//3、选择操作
int len=0;
/*3-1: 不借助数组,简单粗暴
while ((len=bStream.read())!=-1) { //等于说读一个字节输出一个字节
System.out.print((char)len);
}*/
//4、可以释放内存,保持统一 ,但其方法是个空方法 ,没什么卵用
bStream.close();
//3-2 :借助数组,常用方法
byte butter[] =new byte[5];
/*
while ((len=bStream.read(butter))!=-1) {//往butter读取每5个字符,解码换行输出一回。 循环往复
String msg=new String(butter,0,butter.length);
System.out.println(msg);
}*/ //-------------分隔符----写数据(往内存中写,这里内存实际就是输出流的缓冲区)--- ByteArrayOutputStream bStream2=new ByteArrayOutputStream();//默认构建一个32字节的缓冲区,且内容会自动增加)
bStream2.write(src);//把经过编码后的字节src 写入到内存中,也就是输出流缓冲区
byte[] dest=bStream2.toByteArray();//向缓冲区取数据
System.out.println(dest.length+"-->>"+new String(dest,0,dest.length));//数据展示 } }

【综合练习-复制图片】

 /** 复制一张图片 所有东西都能读到字节数组中
* 前面4种流的综合
* ByteArrayInputStream /ByteArrayOutputStream FileInputStream/FileOutputStream
* 图片---FileInputStream------->(借助程序作中转,Java虚拟机)---ByteArrayOutputStream------>字节数组中(内存)
* 字节数组(内存)----ByteArrayInputStream---->(借助程序作中转,Java虚拟机)---FileOutputStream-------->图片
*
*/
package cn.sxt.test; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; public class Test_0401_CopyImage {
public static void main(String[] args) throws IOException {
byte[] srcFile= fileToByteArray("SongYi.jpg");
System.out.println(srcFile.length);//输出源文件图片的大小
ByteArrayToFile(srcFile, "SongYi_copy.jpg"); }
//1、图片到字节数组 传进去一个源文件路径。 图片-->程序--->字节数组
public static byte[] fileToByteArray(String srcFilePath) throws IOException { InputStream iStream=new FileInputStream(srcFilePath);//图片-->程序
ByteArrayOutputStream oStream=new ByteArrayOutputStream();//程序-->字节数组
byte buffer[]=new byte[1024*10]; //缓冲数组
int len=0; //分段读取
while ((len=iStream.read(buffer))!=-1) {
oStream.write(buffer,0,len); }
iStream.close(); return oStream.toByteArray(); } //2、字节数组到图片 字节数组--->程序--->要复制的图片
public static void ByteArrayToFile(byte[] src,String destFilePath) throws IOException { ByteArrayInputStream iStream1=new ByteArrayInputStream(src);//字节数组-->程序 OutputStream oStream1=new FileOutputStream(destFilePath);//程序--->要复制的图片 byte buffer1[]=new byte[1024*10]; //缓冲数组
int len=0; //分段读取
while ((len=iStream1.read(buffer1))!=-1) {
oStream1.write(buffer1,0,len);
}
oStream1.close();
} }

2、ObjectInputStream/ObjectOutputStream(对象字节输入输出流)

当两个进程远程通信时,彼此可以发送各种类型的数据。 无论是何种类型的数据,都会以二进制序列的形式在网络上传送。

比如,我们可以通过http协议发送字符串信息;我们也可以在网络上直接发送Java对象。发送方需要把这个Java对象转换为字节序列,

才能在网络上传送;接收方则需要把字节序列再恢复为Java对象才能正常读取。把Java对象转换为字节序列的过程称为对象的序列化。

把字节序列恢复为Java对象的过程称为对象的反序列化。

对象序列化的作用有如下两种:

1. 持久化: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中,比如:休眠的实现。以后服务器session管理,hibernate将对象持久化实现。

2. 网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信、对象传递。

【代码示例】

 /**2、对象流 ObjectStream
* 输出流:序列化
* 输入流:反序列化
*ObjectOutputStream 对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,
*把得到的字节序列写到一个目标输出流中。这个目标输入流可能是文件,数据库,内存中。
*
ObjectInputStream 对象输入流,它的readObject()方法从一个源输入流中读取字节序列
,再把它们反序列化为一个对象,并将其返回。 只有实现了Serializable接口的类的对象才能被序列化。 Serializable接口是一个空接口,只起到标记作用。
*
* 不是所有的对象都可序列化
*/
package cn.sxt.test; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.PrivateKey;
import java.util.Date; import javax.tools.JavaCompiler; public class Test_0401_ObjectStream {
public static void main(String[] args) throws IOException, ClassNotFoundException { ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream dos=new ObjectOutputStream(baos); dos.writeUTF("编码");
dos.writeInt(345);
//写入:序列化
dos.writeObject("编码好痛苦");//字符串也是一个对象
dos.writeObject(new Date());
dos.writeObject(new Employee("李白",3458.4)); dos.flush(); //错误原因:byte[] datas=baos.toByteArray();放在了oos.writeInt(14);oos.flush();的前边,应该在后边
byte[] datas=baos.toByteArray(); //DataInputStream dis=new DataInputStream(new ByteArrayInputStream(datas)); ByteArrayInputStream bis=new ByteArrayInputStream(datas);
ObjectInputStream dis=new ObjectInputStream(bis); //读取 :反序列化
String msg=dis.readUTF();
System.out.println(msg);
System.out.println(dis.readInt());
System.out.println(dis.readObject());
System.out.println(dis.readObject());
//System.out.println(dis.readObject());
//同理前边的字符串类也可以这样操作
Object employee=dis.readObject();
if (employee instanceof Employee) {//如果employee 是Employee类的实例化对象则输出
Employee employeetemp=(Employee)employee;//而且可以强制转换一下
System.out.println(employeetemp); System.out.println("名字:"+employeetemp.getName());
//可以看出薪水的属性加了transient透明修饰,这里的返回值为0.0
System.out.println("薪水:"+employeetemp.getSalary()); } } } //自己定义的一个类,称之为Javabean封装数据用的。这里还必须要序列化(Serializable),加个牌照,否则虚拟机后拦截的
class Employee implements java.io.Serializable{
private String name; private transient double salary;//transient:短暂的,临时的 这里翻译为透明的、隐身的.敏感数据可以用。这里不需要序列化 //按键alt+shift+s 出现上面菜单 无参构造 : 快捷键 下边 Generate Constructors from Supperclass..
//.根据基类的构造函数生成构造函数,生成和基类参数相同的构造函数,并同时调用基类的构造函数。
public Employee() {
super();
} //构造方法 Generate Constructor using Fields...
// 使用类属性生成构造函数,就是说会生成使用你定义好的属性作为参数的构造函数。
public Employee(String name, double salary) {
super();
this.name = name;
this.salary = salary;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public double getSalary() {
return salary;
} public void setSalary(double salary) {
this.salary = salary;
} //重写 toString 方法
public String toString() {
return "雇员 [name=" + name + ", salary=" + salary + "]";
} }

4-2:DataInputStream/DataOutputStream(数据输入/输出流)

【代码示例】

 /**
*4-2:DataInputStream/DataOutputStream(数据输入/输出流)
*用途:方便处理8大基本数据类型
*1) 先写出后读取
*2) 读取顺序和写出保持一致
*
*/
package cn.sxt.test; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; public class Test_0401_DataStream {
public static void main(String[] args) throws IOException {
//先搞个节点流ByteArrayInputStream /ByteArrayOutputStream或FileInputStream/FileOutputStream
//然后让装饰流去操作他们,否则装饰流就是无源之水,无本之木。//默认构建一个32字节的缓冲区,且内容会自动增
//ByteArrayOutputStream bos=new ByteArrayOutputStream();//这个流不用关闭 //写出,使用数组作为节点流时
FileOutputStream out = new FileOutputStream("D:/a1.txt");
DataOutputStream dos=new DataOutputStream(out); //byte[] datas=bos.toByteArray();//转成字节放在字节数组中 dos.writeChar('a');
dos.writeInt(10);
dos.writeDouble(Math.random());
dos.writeBoolean(true);
dos.writeUTF("Are you OK");
dos.flush(); //读取顺序与写入保持一致
//ByteArrayInputStream bis=new ByteArrayInputStream(datas);//从字节数组中读取
FileInputStream in = new FileInputStream("D:/a1.txt");
DataInputStream dis=new DataInputStream(in); System.out.println("char: " + dis.readChar());
System.out.println("int: " + dis.readInt());
System.out.println("double: " + dis.readDouble());
System.out.println("boolean: " + dis.readBoolean());
System.out.println("String: " + dis.readUTF()); dos.close();
dis.close(); //数组作为字节流
/* ByteArrayOutputStream baos=new ByteArrayOutputStream();
DataOutputStream dos=new DataOutputStream(baos); dos.writeUTF("编码");
dos.writeInt(345);
dos.flush(); byte[] datas=baos.toByteArray(); //DataInputStream dis=new DataInputStream(new ByteArrayInputStream(datas)); ByteArrayInputStream bis=new ByteArrayInputStream(datas);
DataInputStream dis=new DataInputStream(bis);*/ } }

4-3:【独有】PrintStream打印输出流、处理流

【代码示例】

 /**
* 学习4-3:打印流、处理流PrintStream
*
*/
package cn.sxt.test; import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter; public class Test_0401_PrintStream {
public static void main(String[] args) throws FileNotFoundException {
PrintStream pStream=System.out;
pStream.println("人生如逆旅"); //输出内容到控制台
pStream.println(true);
//2个打印流的效果一样
PrintWriter pWriter=new PrintWriter(new FileOutputStream("print3.txt"),true);
pWriter.print("学习Java");
pWriter.close(); FileOutputStream file=new FileOutputStream("print.txt");
PrintStream pStream2=new PrintStream(file,true);//在里面放个字节流 true:使用自动刷新的功能
pStream2.println(false); //输出内容到文件
pStream2.println("人生苦短,学习要趁早!");
pStream2.println("java is best"); //重定向输出端 把原本输出到控制台的输出到文件中去
System.setOut(pStream2);
pStream2.println("改变自己");
//重定向回去控制台 FileDescriptor.out 标准的输入输出端
FileOutputStream file2=new FileOutputStream(FileDescriptor.out);
PrintStream pStream3=new PrintStream(file2,true);
System.setOut(pStream3);
pStream3.println("back"); /*//效果一样
System.setOut(pStream);
pStream.print("回来了");*/ pStream.close();
pStream2.close();
pStream3.close();
} }

[19/04/01-星期一] IO技术_字节流分类总结(含字节数组(Array)流、字节数据(Data)流、字节对象(Object)流)的更多相关文章

  1. [19/03/31-星期日] IO技术_四大抽象类_字符流( 字符输入流 Reader、 字符输出流 Writer )(含字符缓冲类)

     一.概念 Reader Reader用于读取的字符流抽象类,数据单位为字符. int read(): 读取一个字符的数据,并将字符的值作为int类型返回(0-65535之间的一个值,即Unicode ...

  2. [19/04/02-星期二] IO技术_字符流分类总结(含字符转换流InputStreamReader/ OutputStreamWriter,实现字节转字符)

    一.概念 ------->1.BufferedReader/BufferedWriter [参考19.03.31文章] *Reader/Writer-------->2.InputStre ...

  3. [19/03/30-星期六] IO技术_四大抽象类_ 字节流( 字节输入流 InputStream 、字符输出流 OutputStream )_(含字节文件缓冲流)

    一.概念及分类 InputStream(输入流)/OutputStream(输出流)是所有字节输入输出流的父类 [注]输入流和输出流的是按程序运行所在的内存的角度划分的 字节流操作的数据单元是8的字节 ...

  4. [19/03/28-星期四] IO技术_基本概念&字符编码与解码

    一.概念 输入(Input)  指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据) 常见的应用: Ø 读取硬盘上的文件内容到程序.例如:播放器打开一个视频文件.word打开一个do ...

  5. [19/04/03-星期三] IO技术_其它流(RandomAccessFile 随机访问流,SequenceInputStream 合并流)

    一.RandomAccessFile 随机访问流 [版本1] /* *RandomAccessFile 所谓随机读取就是 指定位置开始或指定位置结束 的读取写入文件 * 实现文件的拆分与合并 模拟下载 ...

  6. [19/04/12-星期五] 多线程_任务定时调度(Timer、Timetask和QUARTZ)

    一.Timer和Timetask 通过Timer和Timetask,我们可以实现定时启动某个线程. java.util.Timer 在这种实现方式中,Timer类作用是类似闹钟的功能,也就是定时或者每 ...

  7. [19/04/08-星期一] 多线程_线程的优先级(Priority) 和 守护线程(Daemon)

    一.概念 1. 处于就绪状态的线程,会进入“就绪队列”等待JVM来挑选. 2. 线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5. 3. 使用下列方法获得或设置线程对象的优先级. in ...

  8. [19/04/06-星期六] 多线程_静态代理(StaticProxy)和 lamda (简化代码,jdk8新增)

    一.静态代理 [代码示例] /*** * 静态代理:记录日志等,类是写好的,直接拿来用. 动态代理:随用随构建,临时抱佛脚 * 婚庆公司:代理角色,帮你搞婚庆的一切,布置房间等等 * 自己:真实角色, ...

  9. java ->IO流_字节流

    字节流 在前面的学习过程中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现在我们就要开始给文件中写数据,或者读取文件中的数据. 字节输出流OutputStream OutputStre ...

随机推荐

  1. C#按行读取文本并存放再数组内

    我只想说真的是日了狗的麻烦,代码就那么几行,但是根本看不懂在搞些什么东西,我现在还是一点都不知道getline函数到底是怎么用的,但是事实就是他确实能用. 期间在那该死的第一个char根本不知道为什么 ...

  2. 《深入浅出WPF》重点摘要(—)Binding自动通知机制

    最近因为公司的项目需要用WPF开发,就学习了一下WPF.刚开始只是用到什么就百度什么,虽然功能是实现了,但还是没有弄清楚原理(如果不弄清原理,会感觉很心虚,整个人会没底气),所以决定找个教程系统地学一 ...

  3. 路由器的nat模式、路由模式和全模式

    NAT模式.此模式下,由局域网向广域网发送的数据包默认经过NAT转换,但路由器对所有源地址与局域网接口不在同一网段的数据包均不进行处理.例如,路由器LAN口IP设置为192.168.1.1,子网掩码为 ...

  4. Unreal Engine 4(虚幻UE4)GameplayAbilities 插件入门教程(七)Ability的信息传递等

    本节及后面的内容将会探索更加有意思的内容,更加逼近实际的使用的内容.我们本节内容不难,讲的是释放Ability时的信息传递: 第一步:创建一个GA称为GA_AOE_BlindVengeance,复仇忌 ...

  5. 阿里云API网关(4)快速入门(开放 API)

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  6. mac查看git路径

    mac查看git路径

  7. Genymotion模拟器无法直接安装APP

    使用Genymotion模拟器安装APP的过程中,将我们的apk拖进去模拟器报以下错误: Genymotion官网常见问题解决办法汇集地址:https://www.genymotion.com/#!/ ...

  8. CSS之display样式

    一.前言 行内标签:类似span,无法设置高度,宽度,padding,margin 块级标签:类似div,可以设置高度,宽度,padding,margin 默认情况下是这个样子的,但是可以通过disp ...

  9. 如何从官网开始 mongo java

    http://docs.mongodb.org/ecosystem/drivers/ MongoDB Driver Documentation Getting Started Installation ...

  10. PHP 杂项函数

    PHP 杂项 函数 PHP 杂项函数简介 我们把不属于其他类别的函数归纳到杂项函数类别. 安装 杂项函数是 PHP 核心的组成部分.无需安装即可使用这些函数. Runtime 配置 杂项函数的行为受 ...