1,java io中装饰器的利用例子
package decorationApp;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
//装饰器的典型应用
public class IOTest {
public static void main(String[] args)throws Exception {
//流式读取文件
DataInputStream din = null;
try{
din = new DataInputStream(
new BufferedInputStream(
new FileInputStream("IOTest.txt") //文件放在项目目录下,不是src下,也不是同包下
)
);
//然后就可以获取文件内容了
byte bs []= new byte[din.available()];
din.read(bs);
String content = new String(bs);
System.out.println("文件内容===="+content);
}finally{
if(din!=null)din.close();
}
}
}
仔细观察上面的代码,会发现最里层是一个FileInputStream对象,然后把它传递给一个BufferedInputStream对象,经过BufferedInputStream处理过后,再把处理过后的对象传递给了DataInputStream对象进行处理,这个过程其实就是装饰器的组装过程,FileInputStream对象相当于原始的被装饰的对象,而BufferedInputStream对象和DataInputStream对象则相当于装饰器。
2,自己实现的I/O流的装饰器
来个功能简单点的,实现把英文加密存放吧,也谈不上什么加密算法,就是把英文字母向后移动两个位置,比如:a变成c,b变成d,以此类推,最后的y变成a,z就变成b,而且为了简单,只处理小写的,够简单的吧。
package decorationApp;
import java.io.IOException;
import java.io.OutputStream;
/**
* 实现简单的加密,对OutputStream进行装饰
*/
public class EncryptOutputStream extends OutputStream{
//持有被装饰的对象
private OutputStream os = null;
public EncryptOutputStream(OutputStream os){
this.os = os;
}
public void write(int a) throws IOException {
//先统一向后移动两位
a = a+2;
//97是小写的a的码值
if(a >= (97+26)){
//如果大于,表示已经是y或者z了,减去26就回到a或者b了
a = a-26;
}
this.os.write(a);
}
}
测试程序:
package decorationApp;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class Client {
public static void main(String[] args) throws Exception {
//流式输出文件
DataOutputStream dout = new DataOutputStream(
new BufferedOutputStream(
//这是我们加的装饰器
new EncryptOutputStream(
new FileOutputStream("MyEncrypt.txt")))); //如果没有项目目录下没有此文件,会自动创建该文件
//然后就可以输出内容了
dout.write("abcdxyz".getBytes()); //如果文件中有内容将被重新写入
dout.close();
}
}
生成的MyEncrypt.txt文件中内容:cdefzab
如果上面的程序,装饰器的顺序改变如下:
//流式输出文件
DataOutputStream dout = new DataOutputStream(
//换了个位置
new EncryptOutputStream (
new BufferedOutputStream(
new FileOutputStream("MyEncrypt.txt"))));
这个时候输出的文件一片空白,什么都没有。这是哪里出了问题呢?
(1)先看看成功输出流中的内容的写法的运行过程:
•当执行到“dout.write("abcdxyz".getBytes());”这句话的时候,会调用DataOutputStream的write方法,把数据输出到BufferedOutputStream中;
•由于BufferedOutputStream流是一个带缓存的流,它默认缓存8192byte,也就是默认流中的缓存数据到了8192byte,它才会自动输出缓存中的数据;
•而目前要输出的字节肯定不到8192byte,因此数据就被缓存在BufferedOutputStream流中了,而不会被自动输出
•当执行到“dout.close();”这句话的时候:会调用关闭DataOutputStream流,这会转调到传入DataOutputStream中的流的close方法,也就是BufferedOutputStream的close方法,而BufferedOutputStream的close方法继承自FilterOutputStream,在FilterOutputStream的close方法实现里面,会先调用输出流的方法flush,然后关闭流。也就是此时BufferedOutputStream流中缓存的数据会被强制输出;
•BufferedOutputStream流中缓存的数据被强制输出到EncryptOutputStream流,也就是我们自己实现的流,没有缓存,经过处理后继续输出;
•EncryptOutputStream流会把数据输出到FileOutputStream中,FileOutputStream会直接把数据输出到文件中,因此,这种实现方式会输出文件的内容。
(2)再来看看不能输出流中的内容的写法的运行过程:
•当执行到“dout.write("abcdxyz".getBytes());”这句话的时候,会调用DataOutputStream的write方法,把数据输出到EncryptOutputStream中;
•EncryptOutputStream流,也就是我们自己实现的流,没有缓存,经过处理后继续输出,把数据输出到BufferedOutputStream中;
•由于BufferedOutputStream流是一个带缓存的流,它默认缓存8192byte,也就是默认流中的缓存数据到了8192byte,它才会自动输出缓存中的数据;
•而目前要输出的字节肯定不到8192byte,因此数据就被缓存在BufferedOutputStream流中了,而不会被自动输出
•当执行到“dout.close();”这句话的时候:会调用关闭DataOutputStream流,这会转调到传入DataOutputStream流中的流的close方法,也就是EncryptOutputStream的close方法,而EncryptOutputStream的close方法继承自OutputStream,在OutputStream的close方法实现里面,是个空方法,什么都没有做。因此,这种实现方式没有flush流的数据,也就不会输出文件的内容,自然是一片空白了。
分享到:
相关推荐
在Unix操作系统环境中,I/O(Input/Output)操作是程序与外部设备交互的关键途径,包括读取数据、写入数据以及控制硬件设备等。在处理多个文件或套接字时,I/O聚集和分离是优化性能和管理资源的重要手段。本篇文章将...
单片机I/O口E2PROM读写程序是一个关键的技术环节,在许多嵌入式系统设计中都会用到。E2PROM(Electrically Erasable Programmable Read-Only Memory),即电可擦除可编程只读存储器,是一种非易失性存储器,即使断电...
在Java I/O中,还有缓冲流(Buffered Streams)和装饰器模式的应用。例如,`BufferedReader`和`BufferedWriter`通过在实际读写操作之前存储数据,提高了读写性能。装饰器模式则允许在不改变原有类结构的基础上,动态...
- **GIVEIO驱动**:在Windows中,GIVEIO是一种特殊的驱动技术,用于让普通用户模式程序获取对I/O端口的访问权限。通常,只有管理员级别的驱动程序才能直接访问I/O端口,但GIVEIO可以让非管理员程序也能实现这一功能...
Java I/O流通讯录是一个基于Java编程语言设计的实用程序,它主要用于演示和学习Java的I/O流操作。在这个项目中,开发者通过I/O流实现了对文件的读写功能,从而构建了一个简单的通讯录系统。这个系统允许用户进行添加...
在学习C语言时,理解和掌握顺序结构及I/O操作是至关重要的基础知识。 顺序结构是编程中最基本的逻辑控制方式,它指的是程序按照代码行的顺序逐条执行。在C语言中,从上到下、从左到右的顺序执行是默认的行为。例如...
在文件I/O中,当程序读取一个文件的一部分时,预读策略可能会读取后续的数据到内存,这样当程序需要这些数据时,它们已经准备就绪,从而减少了等待时间。 预读可以提高用户体验,特别是在处理大文件或者连续读取...
在数字I/O中,由于其具有多种功能,噪声的侵入方式也不尽相同。特别值得关注的是采用互补金属氧化物半导体(CMOS)技术的ADC,因其使用单端输出方式,更容易受到噪声干扰。相比于CMOS输出,低压差分信号(LVDS)输出...
在Linux操作系统中,异步I/O(Asynchronous Input/Output,简称AIO)是一种高效的I/O操作模式,它允许应用程序在发起I/O操作后立即继续执行其他任务,而无需等待I/O操作完成。这种模式显著提高了系统的并发性能,...
程序中需要包含初始化I/O口、设置ADC0808工作模式、选择通道、启动转换、读取结果以及处理数码管显示的代码。数码管显示部分通常涉及驱动电路设计和段码控制,通过单片机的I/O口输出相应的段码和位选信号,使得...
(3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。 (4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。 (5)如果一个服务器要处理多个服务或多个协议,一般...
平常学习的时候,java中的I/O流中的知识比较的杂乱,但是有时候需要用到,因此特意整理了下,这在进行分享的
在异步I/O中,通常会用到信号(signal)或事件通知机制来告知应用程序I/O操作何时完成。例如,`aio_read`函数用于发起异步读操作,其中的`struct aiocb`结构体包含了关于I/O请求的信息,包括一个`sigevent`结构,...
在文件I/O中会用到一些相关的概念和术语,包括文件引用旬柄、文件格式、流程控件、流盘等。 1.文件路径 文件路径分为绝对路径和相对路径。绝对路径指文件在磁盘中的位置,LabVIEW可以通过绝对路径访问在磁盘...
在计算机系统中,I/O(Input/Output)端口是CPU与外部设备进行数据交换的重要通道。本章主要探讨的是I/O端口地址译码技术,这是计算机硬件设计中的一个关键部分,尤其对于微机接口而言,理解这一技术至关重要。 ...
在文件I/O中会用到一些相关的概念和术语,包括文件引用旬柄、文件格式、流程控件、流盘等。 1.文件路径 文件路径分为路径和相对路径。路径指文件在磁盘中的位置,LabVIEW可以通过路径访问在磁盘中的文件;...
重叠输入输出(Overlapped I/O)是Windows操作系统中的一种高级I/O机制,它允许在数据传输过程中同时执行其他操作,从而提高了程序的效率和响应性。在本例中,我们将探讨如何使用重叠I/O从HTTP服务器接收文件。 在...
在这个实验中,学生将掌握单片机的基本输入/输出(I/O)操作,以及如何通过编程控制硬件设备。 流水灯通常由多个LED灯组成,它们依次亮起,然后熄灭,形成流动的效果。这个过程涉及到单片机对I/O口的操作,包括设置...