[19/04/01-星期一] IO技术_字节流分类总结(含字节数组(Array)流、字节数据(Data)流、字节对象(Object)流)
一、字节流分类概括
-->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)流)的更多相关文章
- [19/03/31-星期日] IO技术_四大抽象类_字符流( 字符输入流 Reader、 字符输出流 Writer )(含字符缓冲类)
一.概念 Reader Reader用于读取的字符流抽象类,数据单位为字符. int read(): 读取一个字符的数据,并将字符的值作为int类型返回(0-65535之间的一个值,即Unicode ...
- [19/04/02-星期二] IO技术_字符流分类总结(含字符转换流InputStreamReader/ OutputStreamWriter,实现字节转字符)
一.概念 ------->1.BufferedReader/BufferedWriter [参考19.03.31文章] *Reader/Writer-------->2.InputStre ...
- [19/03/30-星期六] IO技术_四大抽象类_ 字节流( 字节输入流 InputStream 、字符输出流 OutputStream )_(含字节文件缓冲流)
一.概念及分类 InputStream(输入流)/OutputStream(输出流)是所有字节输入输出流的父类 [注]输入流和输出流的是按程序运行所在的内存的角度划分的 字节流操作的数据单元是8的字节 ...
- [19/03/28-星期四] IO技术_基本概念&字符编码与解码
一.概念 输入(Input) 指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据) 常见的应用: Ø 读取硬盘上的文件内容到程序.例如:播放器打开一个视频文件.word打开一个do ...
- [19/04/03-星期三] IO技术_其它流(RandomAccessFile 随机访问流,SequenceInputStream 合并流)
一.RandomAccessFile 随机访问流 [版本1] /* *RandomAccessFile 所谓随机读取就是 指定位置开始或指定位置结束 的读取写入文件 * 实现文件的拆分与合并 模拟下载 ...
- [19/04/12-星期五] 多线程_任务定时调度(Timer、Timetask和QUARTZ)
一.Timer和Timetask 通过Timer和Timetask,我们可以实现定时启动某个线程. java.util.Timer 在这种实现方式中,Timer类作用是类似闹钟的功能,也就是定时或者每 ...
- [19/04/08-星期一] 多线程_线程的优先级(Priority) 和 守护线程(Daemon)
一.概念 1. 处于就绪状态的线程,会进入“就绪队列”等待JVM来挑选. 2. 线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5. 3. 使用下列方法获得或设置线程对象的优先级. in ...
- [19/04/06-星期六] 多线程_静态代理(StaticProxy)和 lamda (简化代码,jdk8新增)
一.静态代理 [代码示例] /*** * 静态代理:记录日志等,类是写好的,直接拿来用. 动态代理:随用随构建,临时抱佛脚 * 婚庆公司:代理角色,帮你搞婚庆的一切,布置房间等等 * 自己:真实角色, ...
- java ->IO流_字节流
字节流 在前面的学习过程中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现在我们就要开始给文件中写数据,或者读取文件中的数据. 字节输出流OutputStream OutputStre ...
随机推荐
- js验证港澳居民通行证号码是否合规
需求:最近要做实名验证的功能,但是验证我们要验证严谨一点,参考了网上关于验证港澳居民通行证号码的代码,总结一下. 代码: function checkHKMacao(code){ var tip = ...
- C#导入Excel|读取Excel方法
OleDbConnection读取 /// <summary> /// 返回Excel数据源 /// </summary> /// < ...
- 安装mysql Install/Remove of the Service Denied!错误的解决办法
在window 的cmd下安装mysql 在mysql的bin目录下面执行: mysqld --install 报错: 信息如下: Install/Remove of the Service Deni ...
- 互联网轻量级框架SSM-查缺补漏第三天
简言:平安夜,继续慵懒的学习.我真的是不喜欢学习··· 第三章认识MyBatis核心组件 3.1 持久层的概念和MyBatis的特点 持久层:可以将业务数据存储带磁盘,具有长期存储的能力.一般执行持久 ...
- 冒泡排序——Python实现
一.排序思想 排序思想参见:https://www.cnblogs.com/luomeng/p/10161794.html 二.python实现 def bubble_sort(nums): &quo ...
- Mybaits插入记录返回主键值
某些情况进行insert时不知道主键值(主键为自增),例如系统新增用户时,有用户序号(主键 自增),用户名,密码.插入时只需插入用户名和密码,之后取得mysql自增的序号. 如下为mysql的usr表 ...
- vscode 快速生成html
在Hbuilder中新建一个htm自动会生成一个标准的html代码,那在vscode得一行一行写吗?太烦了吧,各种关键词搜,哎妈 终于找到了办法,现在这里记录下: 第一步:在空文档中输入 ! 第二 ...
- 前端之body标签中相关标签(一)
一 字体标签 字体标签包含:h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub& ...
- javaScript删除对象、数组中的null、undefined、空对象、空数组方法
这两天在项目中遇到后台需要传的数据为不能有null,不能有空值,而这个数据又是一个庞大的对象,对组集合,所以写了个方法来解决这个问题.为了兼具所有的种类类型,封装了方法,代码如下: let obj = ...
- DevExpress中 TreeList控件的常规配置
//以下为TreeList控件样式相关设置 this.treelist_SystemCfg.BackColor = Color.Transparent; this.treelist_SystemCfg ...