Java IO5:管道流、对象流
前言
前面的文章主要讲了文件字符输入流FileWriter、文件字符输出流FileReader、文件字节输出流FileOutputStream、文件字节输入流FileInputStream,这些都是常见的流类。当然除了这些流类之外,Java还提供了很多的流类给用户使用,本文就看一下别的流。
管道流
管道流主要用于连接两个线程的通信。管道流也分为字节流(PipedInputStream、PipedOutputStream)和字符流(PipedReader、PipedWriter)。比如一个PipedInputStream必须和一个PipedOutputStream对象进行连接而产生一个通信管道,PipedOutputStream向管道中写入数据,PipedInputStream从管道中读取数据。管道流的工作如下图所示:
下面看一下管道流的用法。既然管道流的作用是用于线程间的通信,那么势必有发送线程和接收线程,两个线程通过管道流交互数据。首先写一个发送数据的线程:
![](/assets/blank.gif)
public class Sender implements Runnable {private PipedOutputStream out = new PipedOutputStream();public PipedOutputStream getOutputStream(){return out;}public void run(){String str = "Receiver, 你好!";try{out.write(str.getBytes()); // 向管道流中写入数据(发送)out.close();} catch (IOException e){e.printStackTrace();}} }
![](/assets/blank.gif)
用流写数据的时候注意关注一下,该流是否支持直接写String,不可以的话要用String的getBytes()方法获取字符串的字节。既然有一个发送数据的线程了,接下来来一个接收数据的线程:
![](/assets/blank.gif)
public class Receiver implements Runnable {private PipedInputStream in = new PipedInputStream();public PipedInputStream getInputStream(){return in;}public void run(){String s = null;byte b0[] = new byte[1024];try{int length = in.read(b0);if (-1 != length){s = new String(b0, 0 , length);System.out.println("收到了以下信息:" + s);}in.close();} catch (IOException e){e.printStackTrace();}} }
![](/assets/blank.gif)
两个线程都有了,写一个main线程,利用管道输出流的connect方法连接管道输出流和管道输入流:
![](/assets/blank.gif)
public static void main(String[] args) {try{Sender sender = new Sender();Receiver receiver = new Receiver();Thread senderThread = new Thread(sender);Thread receiverThread = new Thread(receiver);PipedOutputStream out = sender.getOutputStream(); // 写入PipedInputStream in = receiver.getInputStream(); // 读出out.connect(in);// 将输出发送到输入senderThread.start();receiverThread.start();} catch (IOException e){e.printStackTrace();} }
![](/assets/blank.gif)
输出结果应该很明显了,大家都知道,接收线程接收到了来自发送线程通过管道流输出流发送的数据:
收到了以下信息:Receiver, 你好!
注意一下,PipedInputStream运用的是一个1024字节固定大小的循环缓冲区,写入PipedOutputStream的数据实际上保存到了对应的PipedInputStream的内部缓冲区。PipedInputStream执行读操作时,读取的数据实际上来自这个内部缓冲区。如果对应的PipedInputStream输入缓冲区已满,任何企图写入PipedOutputStream的线程都将被阻塞。而且这个写操作线程将一直阻塞,直至出现读取PipedInputStream的操作从缓冲区删除数据。
这意味着,向PipedOutputStream写入数据的线程不应该是负责从对应PipedInputStream读取数据的唯一线程(所以这里开了两个线程分别用于读写)。假定t线程试图一次对PipedOutputStream的write()方法的调用中向对应的PipedOutputStream写入2000字节的数据,在t线程阻塞之前,它最多能够写入1024字节的数据(PipedInputStream内部缓冲区的大小)。然而,一旦t被阻塞,读取PipedInputStream的操作就再也不能出现了,因为t是唯一读取PipedInputStream的线程,这样,t线程已经完全被阻塞。
对象流
序列化,在这篇文章中已经讲得比较清楚了,这一部分主要是再次简单过一下对象流的知识而已。
Java中提供了ObjectInputStream、ObjectOutputStream这两个类用于对象序列化操作,这两个类是用于存储和读取对象的输入输出流类,只要把对象中的所有成员变量都存储起来,就等于保存了这个对象,之后从保存的对象之中再将对象读取进来就可以继续使用此对象。ObjectInputStream、ObjectOutputStream可以帮助开发者完成保存和读取对象成员变量取值的过程,但要求读写或存储的对象必须实现了Serializable接口。
看一下例子,先来一个实现了Serializable接口的实体类Person:
![](/assets/blank.gif)
public class Person implements Serializable {/*** 序列化*/private static final long serialVersionUID = 7827863437931135333L;private transient String name;private int age;private final static String sex = "man";public Person(String name, int age){this.name = name;this.age = age;}public String toString(){return "姓名:" + this.name + ", 年龄:" + this.age + ", 性别:" + sex;} }
![](/assets/blank.gif)
调用ObjectOutputStream和ObjectInputStream写一个序列化和反序列化的方法,我现在D盘下没有"serializable.txt":
![](/assets/blank.gif)
public static void main(String[] args) throws Exception {File file = new File("D:/serializable.txt");serializable(file);deserializable(file); }// 序列化对象方法 public static void serializable(File file) throws Exception {OutputStream outputFile = new FileOutputStream(file);ObjectOutputStream oos = new ObjectOutputStream(outputFile);oos.writeObject(new Person("张三", 25));oos.close(); }// 反序列化对象方法 public static void deserializable(File file) throws Exception {InputStream inputFile = new FileInputStream(file);ObjectInputStream ois = new ObjectInputStream(inputFile);Person p = (Person)ois.readObject();System.out.println(p); }
![](/assets/blank.gif)
现在运行一下,D盘下多了一个"serializable.txt",文件里面的内容是:
看到乱码,因为序列化之后本身就是按照一定的二进制格式组织的文件,这些二进制格式不能被文本文件所识别,所以乱码也是正常的。
当然,控制台上也是有输出的:
姓名:null, 年龄:25, 性别:man
这证明了被transient修饰的成员变量不会被序列化。
转载于:https://www.cnblogs.com/qypx520/p/5736553.html
Java IO5:管道流、对象流相关推荐
- JAVA学习 API_day10(缓冲流, 打印流, 对象流)
缓冲流, 转换流, 打印流, 对象流 1. 缓冲流 1. 字节缓冲流 2. 字符缓冲流 2.打印流 1.字节打印流(了解) 2.字符打印流 3.对象流 1. 缓冲流 1. 字节缓冲流 包装 -> ...
- IO流的字符流+对象流+打印流+内存流+随机访问流(2)
IO流的字符流+对象流+打印流+内存流+随机访问流(2) 一.字符流 1.利用字符输出转换流 向文件写入数据 1.文件存在的情况 2.文件不存在的情况 经验:所有的输出流,当文件不存在时都会创建文件 ...
- java基础 io流 字节流 字符流 节点流 包装流 转换流 缓冲流 对象流 打印流 Properties类
目录 1.概念 2.常用的文件操作 2.1 创建文件 2.2 获取文件相关信息 2.3 目录的操作和文件删除 3. IO流原理及流的分类 3.1 流的分类 4.InputStream 字节输入流 4. ...
- Java深度学习系列——对象流和序列化
前言: 我是张哲,一位在互联网上不愿透露姓名的小学员,接下来大家看到的所有内容都是我背写的知识点,这里的知识点和你所学习到的不同,我中和了我的一些书籍和网上刷的面试笔记,相信这里能让你接触到更深入的知 ...
- 学Java基础19 字符流 编码表 转换流 字符高效流 对象流 序列化 以及所有的IO流总结
一.字符流概述 1.字符流 就是用于来读写字符操作的流 2.字符流使用的原因: 使用字节流来读取文件中中文会出现乱码 因为中文不是一个字节组成的 所以读取中文的时候 需要使用字符流 字符实际上也是使用 ...
- day27-API-java流的三大分类,常用的流(文件流,对象流, 缓冲流, 转换流, PW)
文章目录 一. java流的三大类 1. 输出流和输入流 2. 字节流和字符流 3. 节点流和处理流 二. 字节流 1. 文件流 FIS和FOS 1.1 文件输出流:FileOutputStream ...
- IO流(文件流 , 缓冲流 , 对象流, 字符流 )
IO流父类 输入流InputStream : 硬盘–>内存 输出流OutputStream : 内存–>硬盘 文件流(FileInputStream 和FileOutputStream) ...
- 【java基础,IO合集】文件流、高级流(缓冲流、对象流)、 序列化接口java.io.Serrializable
目录 文件流 1 块读写的文件复制操作 2 文件输出流-覆盖模式 3 文件输出流-追加模式 4 文件输出流-读取文本数据 高级流 1 流连接示意图 2 缓冲流 2.1 使用缓冲流完成文件复制操作 2 ...
- java流与文件——对象流和序列化
[0]README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件--对象流和序列化 的相关知识: 0.2) for source code , pleas ...
- Java基础巩固(二)异常,多线程,线程池,IO流,Properties集合,IO工具类,字符流,对象流,Stream,Lambda表达式
一.异常,多线程 学习目标 : 异常的概述 异常的分类 异常的处理方式 自定义异常 多线程入门 1 异常的概述 1.1 什么是异常? 异常就是程序出现了不正常情况 , 程序在执行过程中 , 数据导致程 ...
最新文章
- 2022-2028年中国光掩膜行业市场行情监测及未来前景规划报告
- sqlalchemy Specified key was too long; max key length is 767 bytes的解决办法
- 通过tomcat实现多域名配置
- Wiew 像写 Android UI 一样写小游戏布局
- PING的原理以及ICMP协议
- 到底使用接口还是抽象类
- .net微软消息队列(msmq)简单案例
- 大家心目中的这些「优质」论文,你读过几篇?| PaperDaily #01
- python内置类属性_Python内置方法和属性应用:反射和单例(推荐)
- AGC019D - Shift and Flip(枚举)
- Spring Cloud构建微服务架构:服务网关(过滤器)【Dalston版】
- LeetCode算法入门- Reverse Integer-day6
- python爬取苏州天气并用excel来保存
- CP三次握手和四次分手--转
- 安装RabbitMq启动运行出现服务无法启动 发生系统错误1067解决方案
- redhat7 上安装dummynet
- Codeforces Round #215 (Div. 2) 解题报告
- mysql 中文手册 pdf_Mysql8.0中文参考手册 中英文chm+pdf版
- 获取用户的openid与遇到的errcode:40029与errcode:40125,errmsg
- 开源crm排名_排名前6位的开源CRM工具
热门文章
- Setup a Windows Server 2012 ×××
- 腾达tenda无线路由器网络拓展wds功能实战配置手册
- 使用taro命令(taro convert)转h5碰到的一些问题
- (技能篇)双机热备之Oracle切换故障处理
- PHP中array_merge函数与array+array的区别
- keras_14_初始化Initializers
- 超炫jQuery测试答题功能
- 真机测试报错ERROR/AndroidRuntime: java.lang.RuntimeException: setParameters failed解决办法
- 微信小程序 最全 生成带参数二维码
- android点击按钮底部暗影,android – 圆形按钮,像5.0 FAB一样的阴影