前言

前面的文章主要讲了文件字符输入流FileWriter、文件字符输出流FileReader、文件字节输出流FileOutputStream、文件字节输入流FileInputStream,这些都是常见的流类。当然除了这些流类之外,Java还提供了很多的流类给用户使用,本文就看一下别的流。

管道流

管道流主要用于连接两个线程的通信。管道流也分为字节流(PipedInputStream、PipedOutputStream)和字符流(PipedReader、PipedWriter)。比如一个PipedInputStream必须和一个PipedOutputStream对象进行连接而产生一个通信管道,PipedOutputStream向管道中写入数据,PipedInputStream从管道中读取数据。管道流的工作如下图所示:

下面看一下管道流的用法。既然管道流的作用是用于线程间的通信,那么势必有发送线程和接收线程,两个线程通过管道流交互数据。首先写一个发送数据的线程:

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();}}
}

用流写数据的时候注意关注一下,该流是否支持直接写String,不可以的话要用String的getBytes()方法获取字符串的字节。既然有一个发送数据的线程了,接下来来一个接收数据的线程:

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();}}
}

两个线程都有了,写一个main线程,利用管道输出流的connect方法连接管道输出流和管道输入流:

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();}
}

输出结果应该很明显了,大家都知道,接收线程接收到了来自发送线程通过管道流输出流发送的数据:

收到了以下信息: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:

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;}
}

调用ObjectOutputStream和ObjectInputStream写一个序列化和反序列化的方法,我现在D盘下没有"serializable.txt":

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);
}

现在运行一下,D盘下多了一个"serializable.txt",文件里面的内容是:

看到乱码,因为序列化之后本身就是按照一定的二进制格式组织的文件,这些二进制格式不能被文本文件所识别,所以乱码也是正常的。

当然,控制台上也是有输出的:

姓名:null, 年龄:25, 性别:man

这证明了被transient修饰的成员变量不会被序列化。

转载于:https://www.cnblogs.com/qypx520/p/5736553.html

Java IO5:管道流、对象流相关推荐

  1. JAVA学习 API_day10(缓冲流, 打印流, 对象流)

    缓冲流, 转换流, 打印流, 对象流 1. 缓冲流 1. 字节缓冲流 2. 字符缓冲流 2.打印流 1.字节打印流(了解) 2.字符打印流 3.对象流 1. 缓冲流 1. 字节缓冲流 包装 -> ...

  2. IO流的字符流+对象流+打印流+内存流+随机访问流(2)

    IO流的字符流+对象流+打印流+内存流+随机访问流(2) 一.字符流 1.利用字符输出转换流 向文件写入数据 1.文件存在的情况 2.文件不存在的情况 经验:所有的输出流,当文件不存在时都会创建文件 ...

  3. java基础 io流 字节流 字符流 节点流 包装流 转换流 缓冲流 对象流 打印流 Properties类

    目录 1.概念 2.常用的文件操作 2.1 创建文件 2.2 获取文件相关信息 2.3 目录的操作和文件删除 3. IO流原理及流的分类 3.1 流的分类 4.InputStream 字节输入流 4. ...

  4. Java深度学习系列——对象流和序列化

    前言: 我是张哲,一位在互联网上不愿透露姓名的小学员,接下来大家看到的所有内容都是我背写的知识点,这里的知识点和你所学习到的不同,我中和了我的一些书籍和网上刷的面试笔记,相信这里能让你接触到更深入的知 ...

  5. 学Java基础19 字符流 编码表 转换流 字符高效流 对象流 序列化 以及所有的IO流总结

    一.字符流概述 1.字符流 就是用于来读写字符操作的流 2.字符流使用的原因: 使用字节流来读取文件中中文会出现乱码 因为中文不是一个字节组成的 所以读取中文的时候 需要使用字符流 字符实际上也是使用 ...

  6. day27-API-java流的三大分类,常用的流(文件流,对象流, 缓冲流, 转换流, PW)

    文章目录 一. java流的三大类 1. 输出流和输入流 2. 字节流和字符流 3. 节点流和处理流 二. 字节流 1. 文件流 FIS和FOS 1.1 文件输出流:FileOutputStream ...

  7. IO流(文件流 , 缓冲流 , 对象流, 字符流 )

    IO流父类 输入流InputStream : 硬盘–>内存 输出流OutputStream : 内存–>硬盘 文件流(FileInputStream 和FileOutputStream) ...

  8. 【java基础,IO合集】文件流、高级流(缓冲流、对象流)、 序列化接口java.io.Serrializable

    目录 文件流 1 块读写的文件复制操作 2 文件输出流-覆盖模式 3 文件输出流-追加模式 4 文件输出流-读取文本数据 高级流 1  流连接示意图 2 缓冲流 2.1 使用缓冲流完成文件复制操作 2 ...

  9. java流与文件——对象流和序列化

    [0]README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件--对象流和序列化 的相关知识: 0.2) for source code , pleas ...

  10. Java基础巩固(二)异常,多线程,线程池,IO流,Properties集合,IO工具类,字符流,对象流,Stream,Lambda表达式

    一.异常,多线程 学习目标 : 异常的概述 异常的分类 异常的处理方式 自定义异常 多线程入门 1 异常的概述 1.1 什么是异常? 异常就是程序出现了不正常情况 , 程序在执行过程中 , 数据导致程 ...

最新文章

  1. 2022-2028年中国光掩膜行业市场行情监测及未来前景规划报告
  2. sqlalchemy Specified key was too long; max key length is 767 bytes的解决办法
  3. 通过tomcat实现多域名配置
  4. Wiew 像写 Android UI 一样写小游戏布局
  5. PING的原理以及ICMP协议
  6. 到底使用接口还是抽象类
  7. .net微软消息队列(msmq)简单案例
  8. 大家心目中的这些「优质」论文,你读过几篇?| PaperDaily #01
  9. python内置类属性_Python内置方法和属性应用:反射和单例(推荐)
  10. AGC019D - Shift and Flip(枚举)
  11. Spring Cloud构建微服务架构:服务网关(过滤器)【Dalston版】
  12. LeetCode算法入门- Reverse Integer-day6
  13. python爬取苏州天气并用excel来保存
  14. CP三次握手和四次分手--转
  15. 安装RabbitMq启动运行出现服务无法启动 发生系统错误1067解决方案
  16. redhat7 上安装dummynet
  17. Codeforces Round #215 (Div. 2) 解题报告
  18. mysql 中文手册 pdf_Mysql8.0中文参考手册 中英文chm+pdf版
  19. 获取用户的openid与遇到的errcode:40029与errcode:40125,errmsg
  20. 开源crm排名_排名前6位的开源CRM工具

热门文章

  1. Setup a Windows Server 2012 ×××
  2. 腾达tenda无线路由器网络拓展wds功能实战配置手册
  3. 使用taro命令(taro convert)转h5碰到的一些问题
  4. (技能篇)双机热备之Oracle切换故障处理
  5. PHP中array_merge函数与array+array的区别
  6. keras_14_初始化Initializers
  7. 超炫jQuery测试答题功能
  8. 真机测试报错ERROR/AndroidRuntime: java.lang.RuntimeException: setParameters failed解决办法
  9. 微信小程序 最全 生成带参数二维码
  10. android点击按钮底部暗影,android – 圆形按钮,像5.0 FAB一样的阴影