一、writer.flush()和writer.close()的区别
- 相同点:都会刷新缓冲区
- 不同点:
- A:flush()只刷新缓冲区,close()先刷新缓冲区然后关闭流.
- B:flush()刷新缓冲区后可以继续写入数据继续刷新缓冲区;close()关闭流后就无法继续写入数据了,否则报流已经关闭异常.
二、编码:将字符数据转换成字节数据的过程
1、如果没有指定编码表,则默认使用本地编码表,当前是中文环境,所以使用的GBK编码表
byte[] data=str.getBytes();
2、手工指定编码表
byte[] data=str.getBytes("gbk");
解码:将字节数据还原成字符数据的过程
String(byte[] bytes)
String decodeInfo=new String(data);
手工指定解码的编码表
String decodeInfo=new String(data,"UTF-8");
三、装饰者模式
1、装饰和继承。
- 装饰设计模式是一种解决某一类问题的思想。该类问题的有效解决方案。解决给类提供增强型功能的问题。
- 继承:是面向对象的特征之一。
Writer
|--TextWriter
|--MediaWirter
该体系的出现已经可以完成对文本数据和媒体数据的写操作。但是发现。效率较低。为了提高效率,就加入了缓冲技术。
文本写入需要缓冲
媒体写入需要缓冲
按照面向对象的思想,为了提高扩展,通过继承的方式完成。
Writer
|--TextWriter
|--BufferedTextWriter
|--MediaWirter
|--BufferedMedieWriter
这就完成了文本和媒体数据写操作效率提高。
当然如果该体系加入一个子类BaseWriter,而且该子类也许要效率提高。
Writer
|--TextWriter
|--BufferedTextWriter
|--MediaWirter
|--BufferedMedieWriter
|--BaseWriter
|--BufferedBaseWriter
如果体系扩展,都需要定义一个该子类具备高效缓冲功能的子类。这样体系扩展很麻烦。
如何把这个体系出现问题解决一下,并优化一下呢?
我们发现,这些子类使用的缓冲技术都是一样的。
缓冲区其实就是定义了临时存储容器将数据进行临时缓冲,至于具体的写操作,还是Writer的子类对象完成的,比如 TextWriter. MediaWriter等。
既然这样,可以将缓冲技术单独封装成一个对象,
要对哪个具体对象进行缓冲技术的使用,只要将该对象传递给缓冲区对象即可。
//对缓冲区对象进行单独描述。
class BufferedWriter extends Writer{
BufferedWriter(Writer w){
}
// BufferedWriter(TextWriter tw)
// {}
// BufferedWriter(MediaWriter dw)
// {}
}
当缓冲技术单独封装成了对象后,它具备的还是写功能,只不过可以其他对象的写功能进行高效。所以它还是Writer类中的一员。
所以这时体系变成了
Writer
|--TextWriter
|--MediaWirter
|--BufferedWriter:这是一个提供增强功能的类。就把这种优化方式,定义成一种最终的解决该问题的解决方案并起个名字:装饰设计模式。
和原来的体系,变的很清爽。
Writer
|--TextWriter
|--BufferedTextWriter
|--MediaWirter
|--BufferedMedieWriter
装饰设计模式的出现可以对一组类进行功能的增强。
而且装饰类本事也是该体系中的一个子类。
代码体现:
通常情况下,装饰类一般不单独存在。都是通过构造函数接收被装饰的对象。基于被装饰的对象的功能,并对外提供增强行的功能。
和继承的区别:
继承会让体系变得臃肿,装饰更为灵活。
在IO中装饰设计模式用的很多。
比如:
BufferedWriter
BufferedReader
*/
class
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
四、重定向
(一)、重定向输入
1、默认情况下,System.in返回的输入流对应的输入设备是用户键盘.
InputStream rawInputStream=System.in;
2、实例化扫码器对象并指定输入流对象
Scanner scanner=new Scanner(rawInputStream);
do{
System.out.print("请从键盘输入信息:");
String content=scanner.next();
if("quit".equals(content)){
break;
}
System.out.println("content="+content);
}while(true);
String path="src"+File.separator+"com"+File.separator+"hsj"+File.separator+"client"+File.separator+"ByteArrayStreamDemo01.java";
try {
3、实例化文件输入流对象并指定文件路径
FileInputStream fileInputStream=new FileInputStream(path);
System.setIn(fileInputStream);//重定向输入
4、实例化扫码器对象并指定输入源对象
scanner=new Scanner(System.in);//此时的System.in对应着文件输入流对象
scanner.useDelimiter("\n");//默认分隔符是空格,不满足要求,我需要手工将分隔符改成换行符才能符合要求.
while(scanner.hasNext()){
String content=scanner.next();
System.out.println(content);
}
5、将输入流重新定向到用户键盘
System.setIn(rawInputStream);
scanner=new Scanner(System.in);
do{
System.out.print("请从键盘输入信息:");
String content=scanner.next();
if("quit".equals(content)){
break;
}
System.out.println("content="+content);
}while(true);
(二)、重定向输出
PrintStream out=System.out;//默认情况下,System.out对应的输出设备是控制台
out.println("你好,世界!");
PrintStream printStream=new PrintStream("hsj.bak");
System.setOut(printStream);//重定向输出
for(int i=0;i<=65535;i++){
System.out.print((char)i+" ");
if(i%80==0){
System.out.println();
}
}
System.setOut(out);//重新将输出设备定位到控制台
System.out.println("我有回来了!");
五、序列化
如果不想让那些字段参与对象的序列化有两种方式:
A:在遍历的前面加上transient关键字
B:将不需要参与序列化的成员变量静态化.