前言

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

管道流

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

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

public class Sender implementsRunnable

{

private PipedOutputStream out = newPipedOutputStream();

publicPipedOutputStream getOutputStream()

{

returnout;

}

public voidrun()

{

String str = "Receiver, 你好!";

try{

out.write(str.getBytes()); //向管道流中写入数据(发送)

out.close();

}

catch(IOException e)

{

e.printStackTrace();

}

}

}

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

public class Receiver implementsRunnable

{

private PipedInputStream in = newPipedInputStream();

publicPipedInputStream getInputStream()

{

returnin;

}

public voidrun()

{

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 voidmain(String[] args)

{

try{

Sender sender = newSender();

Receiver receiver = newReceiver();

Thread senderThread = newThread(sender);

Thread receiverThread = newThread(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 implementsSerializable

{

/*** 序列化

*/

private static final long serialVersionUID = 7827863437931135333L;

private transientString name;

private intage;

private final static String sex = "man";

public Person(String name, intage)

{

this.name =name;

this.age =age;

}

publicString toString()

{

return "姓名:" + this.name + ", 年龄:" + this.age + ", 性别:" +sex;

}

}

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

public static void main(String[] args) throwsException

{

File file = new File("D:/serializable.txt");

serializable(file);

deserializable(file);

}

//序列化对象方法

public static void serializable(File file) throwsException

{

OutputStream outputFile = newFileOutputStream(file);

ObjectOutputStream oos = newObjectOutputStream(outputFile);

oos.writeObject(new Person("张三", 25));

oos.close();

}

//反序列化对象方法

public static void deserializable(File file) throwsException

{

InputStream inputFile = newFileInputStream(file);

ObjectInputStream ois = newObjectInputStream(inputFile);

Person p =(Person)ois.readObject();

System.out.println(p);

}

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

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

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

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

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

java 管道流_Java IO7:管道流、对象流相关推荐

  1. java 写入文件流_Java实现文件写入——IO流

    输入输出的重要性: 输入和输出功能是Java对程序处理数据能力的提高,Java以流的形式处理数据.流是一组有序的数据序列,根据操作的类型,分为输入流和输出流. 程序从输入流读取数据,向输出流写入数据. ...

  2. java 视频流 读取_Java之视频读取IO流解帧实施方案

    获取视频处理对象的方式有很多,读取本地文件.读取url.读取摄像头等,而直接读流解析视频的实施方案却难以寻觅.此处有两种方案处理视频流(此处设定场景为用户上传视频,同时两种方式均需服务端安装ffmpe ...

  3. java inputstream理解_Java进阶核心之InputStream流深入讲解

    Java核心包 java.io包介绍 IO: Input / Ouput 即输入输出 输出流:程序(内存) ->外界设备 输入流:外界设备->程序(内存) 处理理数据类型分类 字符流:处理 ...

  4. java中什么是字节流和字符流_java中字节流与字符流的区别是什么

    字节(Byte)是进行io操作的基本数据单位,在程序进行字节数据输出时可以使用OutputStream类完成 此类定义如下: public abstract class OutputStream ex ...

  5. java imageio 使用_java – 使用ImageIO发送图像流?

    我有一个ServerSocket和一个Socket设置,所以ServerSocket使用ImageIO.write(-.)发送图像流,Socket尝试读取它们并用它们更新JFrame.所以我想知道Im ...

  6. java数据成员_Java基础教程之对象的方法与数据成员

    在Java基础教程之从Hello World到面向对象一文中,我们初步了解了对象(object).对象中的数据成员表示对象的状态.对象可以执行方法,表示特定的动作. 此外,我们还了解了类(class) ...

  7. java并发常量_Java并发编程-常量对象(七)

    在创建后状态不再发生改变的对象称作常量对象(Immutable Objects).常量对象其可靠性使其广泛地用作开发简单可靠代码的策略.常量对象在开发并发程序中非常有用.由于创建后不能被改变状态,它们 ...

  8. java超类 子类_Java超类引用子类对象的规律

    首先,对于JVM实现引用的一个机制是:类实例的引用就是指向一个句柄(handle)的指针,这个句柄就是一堆指针:一个指针指向一块从java堆中为分配出来内存空间:另一个指针指向一张表(实际上这个表格也 ...

  9. java全局变量加锁_Java锁Synchronized,对象锁和类锁举例

    4. 同步加锁的是对象,而不是代码.因此,如果你的类中有一个同步方法,这个方法可以被两个不同的线程同时执行,只要每个线程自己创建一个的该类的实例即可. 5. 不同的对象实例的synchronized方 ...

最新文章

  1. iOS 流式播放音频文件
  2. java ef 引用问题_java调用shell(ps -ef | grep )问题
  3. Java技术:SpringBoot集成FreeMarker生成word文件
  4. LeetCode:Remove Nth Node From End of List 移除链表倒第n项
  5. nodejs 下载url文件
  6. gb28181简单实现sip信令服务器(java版基于springboot):三、sip摄像头注册(代码实现)
  7. [渝粤教育] 内蒙古大学 微生物学 参考 资料
  8. 多线程和高并发的区别
  9. 【PDF合并】滴滴出行电子发票及行程报销单【一页打印】
  10. ubuntu安装docker + 配置国内源和加速器
  11. Gremlin 基础知识
  12. rtx3060ti、rtx3060和rtx2080ti 参数对比哪个好 差距大不大
  13. 【原创】PE检测工具
  14. 怎么安装苹果系统mac os x虚拟机
  15. 一次日语翻译的Chrome插件开发经历
  16. Synopsys DC 笔记
  17. 专题地图怎么做,怎么打印地图?
  18. 手工DIY:手机变身扫描仪_极客迷
  19. 游戏服务器千人同屏的思考
  20. ADS129X芯片中文资料(一)——用于生理信号测量的芯片

热门文章

  1. Git 基础(九)—— Failed to push some refs to git
  2. 标准模板库(STL)之 vector 列传 (二)
  3. 复数相关的等式及证明
  4. python绘制曲线y=2x+5_Python数据可视化:Matplotlib绘图详解(二)
  5. 零基础学python知乎-编程零基础应当如何开始学习 Python?
  6. python工资这么高为什么不学-现在Python就业薪资高吗?
  7. 尚硅谷python全套-尚硅谷Java视频教程,粉丝无数,人手一套尚硅谷教程
  8. python入门先学什么-Python入门学习 DAY 01 计算机基础
  9. 干货|详解最新语音识别框架 深度全序列卷积神经网络
  10. 语音性别识别_语音识别识别性别_语音文字识别 - 云+社区 - 腾讯云