Java:IO系统与装饰模式

    Java的IO流有三种分法:

①输入流、输出流:输入输出流都是以Java程序为参照的。

②字节流、字符流:字节是存储单位,占8位,其他基本数据类型都用字节来衡量大小。字符是数字字母等字符,ASCII和Unicode都是字符编码集,ASCII码是8位一个字节的,Unicode是16位两个字节的,而Java字符编码是采用Unicode的。字节流后缀是Stream字符流后缀是Reader,Writer。

③节点流、处理流:节点流可以理解为真正处理数据的流,处理流是在节点流的基础上的修饰。

关于各种流的分类可以参考以下文章:http://blog.csdn.net/yuebinghaoyuan/article/details/7388059


实例一:用字节节点流FileInputStream、FileOutputStream和字符节点流FileReader、FileWriter读写文件

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test {
	public static void main(String[] args) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fis = new FileInputStream("D:/From.txt"); // 在D盘新建一个From.txt文本文件,里面内容是abcd   
			byte[] buffer = new byte[64]; // 将输入流的数据读取到字节数组
			int temp = fis.read(buffer); 
			System.out.println(buffer[0]); // Unicode编码,所以打印出ASCII码97
			System.out.println(new String(buffer));
			fos = new FileOutputStream("D://To.txt"); // 将字节数组的数据写到To.txt文本文件
			fos.write(buffer, 0, temp); // 读写大文件用个while循环就可以
	
			fr = new FileReader("D:/From1.txt"); // 同上
			fw = new FileWriter("D:/To1.txt"); // 内容是zxcv
			char[] buf = new char[64];
			int temp1 = fr.read(buf);
			System.out.println(buf[0]);
			System.out.println(new String(buf));
			fw.write(buf, 0, temp1);
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} finally {                                        //将所有输入流和输出流关闭
			try {
				fis.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			try {
				fos.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			try {
				fr.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			try {
				fw.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
	}
}
打印结果:

97
abcd
z
zxcv


实例二:用修饰字符节点流FileReader的BufferedReader处理流来读写文件

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		FileReader fr = null;
		BufferedReader br = null;
		try {
			fr = new FileReader("d:/From2.txt"); // 内容是第一行:abcd,第二行:efgh,第三行:ijk
			br = new BufferedReader(fr); // 传递的参数是一个节点字符流
			String line;
			while ((line = br.readLine()) != null) { // 此处理流比节点流多了个readLine方法,可以一次性读取一行
				System.out.println(line);
			}
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} finally {
			try {
				fr.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			try {
				br.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}

	}
}
打印结果:

abcd
efgh
ijk

处理流就是在节点流的基础上添加一些功能,这是一种装饰模式。


实例三:简单的装饰模式理解

①新建一个Student接口

public interface Student {
	public void study();
}
②新建两个实现类

public class WenkeStudent implements Student {
	private String name;

	public WenkeStudent(String name) {
		this.name = name;
	}

	@Override
	public void study() {
		// TODO 自动生成的方法存根
		System.out.println(name+"学习文科");
	}
}

public class LiKeStudent implements Student {
	private String name;

	public LiKeStudent(String name) {
		this.name = name;
	}

	@Override
	public void study() {
		// TODO 自动生成的方法存根
		System.out.println(name + "学习理科");
	}
}

③新建一个装饰类

public class DecorateStudent {

	private Student student;   // 这是整个模式的关键,在装饰类中有一个被装饰者的接口引用
<span style="white-space:pre">				</span>   // 构造器中传进的参数则应是接口的实现类对象向上转型为接口<span style="white-space:pre">		</span>
	public DecorateStudent(Student student) { 
		super();
		this.student = student; 
	}

	public void study_well() {  // 添加两个修饰方法
		student.study();
		System.out.println("很强");
	}

	public void study_bad() {
		student.study();
		System.out.println("很差");
	}

}

④Main函数

public class Test {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		DecorateStudent decorateStudent = new DecorateStudent(new LiKeStudent(
				"张三"));
		decorateStudent.study_well();
		DecorateStudent decorateStudent2 = new DecorateStudent(
				new WenkeStudent("李四"));
		decorateStudent2.study_bad();
	}

}
打印结果:

张三学习理科
很强
李四学习文科
很差

和IO系统作为参照分析一下上面这个实例:Student接口相当于InputStream、OutputStream、Reader、Writer等基类;WenkeStudent、LikeStudent相当于FileInputstream、FileOutputStream、FileReader、FileWriter等继承类;DecorateStudent类相当于BufferedReader等处理流类;study_well方法就相当于readLine方法。这样对比应该就可以明白一点。






郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。