黑马程序员_java的IO流五_18

来源:互联网 发布:unity3d 画线插件 编辑:程序博客网 时间:2024/05/20 21:19

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

 

一,java的管道流

1.引言

Java I/O系统是建立在数据流概念之上的,而在UNIX/Linux中有一个类似的概念,就是管道,它具有将一个程序的输出当作另一个程序的输入的能力。在Java中,可以使用管道流进行线程之间的通信,输入流和输出流必须相连接,这样的通信有别于一般的Shared Data通信,其不需要一个共享的数据空间。

2.相关类及其关系

1)字节流:

分为管道输出流(PipedOutputStream)和管道输入流(PipedInputStream),利用 java.io.PipedOutputStream和java.io.PipedInputStream可以实现线程之间的二进制信息传输。如果要进行管道输出,则必须把输出流连在输入流上。 java.io.PipedOutputStream是java.io.OutputStream的直接子类,而java.io. PipedInputStream是java.io.InputStream的直接子类。PipedOutputStream和 PipedInputStream往往成对出现、配合使用。举例说明:

不写入就没有办法读到!

注意:

PipedInputStream中实际是用了一个1024字节固定大小的循环缓冲区。写入PipedOutputStream的数据实际上保存到对应的 PipedInputStream的内部缓冲区。从PipedInputStream执行读操作时,读取的数据实际上来自这个内部缓冲区。如果对应的 PipedInputStream输入缓冲区已满,任何企图写入PipedOutputStream的线程都将被阻塞。而且这个写操作线程将一直阻塞,直至出现读取PipedInputStream的操作从缓冲区删除数据。这也就是说往PipedOutputStream写数据的线程Send若是和从PipedInputStream读数据的线程Receive是同一个线程的话,那么一旦Send线程发送数据过多(大于1024字节),它就会被阻塞,这就直接导致接受数据的线程阻塞而无法工作(因为是同一个线程嘛),那么这就是一个典型的死锁现象,这也就是为什么javadoc中关于这两个类的使用时告诉大家要在多线程环境下使用的原因了。

二,Java RandomAccessFile的使用

java的RandomAccessFile提供对文件的读写功能,与普通的输入输出流不一样的是RamdomAccessFile可以任意的访问文件的任何地方。这就是“Random”的意义所在。RandomAccessFile的对象包含一个记录指针,用于标识当前流的读写位置,这个位置可以向前移动,也可以向后移动。RandomAccessFile包含两个方法来操作文件记录指针。

1.RandomAccessFile的构造方法如下

public RandomAccessFile(File file,String mode) throws FileNotFoundException

创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。将创建一个新的 FileDescriptor 对象来表示此文件的连接。 mode 参数指定用以打开文件的访问模式。允许的值及其含意为:值含意
 "r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。 
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。 
"rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。 
"rwd"   打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备

 

long getFilePoint():记录文件指针的当前位置。

void seek(long pos):将文件记录指针定位到pos位置。

RandomAccessFile包含InputStream的三个read方法,也包含OutputStream的三个write方法。同时RandomAccessFile还包含一系列的readXxx和writeXxx方法完成输入输出。

2.实例演示

 

3.具体应用:

应用在实现数据的分段写入:用一个线程负责一段数据的写入,互相不会冲突。就好比是下载软件的原理,多线程下载往一个硬盘里写数据。不能用一般的流写,因为写的数据不是连续的,解码错误,无法读取

三,ByteArrayInputStream和ByteArrayOutputstream

此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray()和 toString()获取数据关闭ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException。 (因为都存到缓冲区中去了) 此类中的方法在关闭此流后仍可被调用。

ByteArrayOutputStream是用来缓存数据的(数据写入的目标(output stream原义)),向它的内部缓冲区写入数据,缓冲区自动增长,当写入完成时可以从中提取数据。由于这个原因,ByteArrayOutputStream常用于存储数据以用于一次写入。

ByteArrayOutputStream类是在创建它的实例时,程序内部创建一个byte型别数组的缓冲区,然后利用ByteArrayOutputStream和ByteArrayInputStream的实例向数组中写入或读出byte型数据。在网络传输中我们往往要传输很多变量,我们可以利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去。具体用法如下:

ByteArrayOutputStream:    可以捕获内存缓冲区的数据,转换成字节数组。

ByteArrayInputStream: 可以将字节数组转化为输入流

 

-------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

详细请查看:<a href="http://www.itheima.com" target="blank">www.itheima.com</a>----

 

0 0