一、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:将不需要参与序列化的成员变量静态化.
如果需要相关视频资料,请加群qq555373607