装饰者模式
将原有的功能进行提升
装饰者模式的书写步骤
1.将被装饰者 当做类中的一个成员变量;
2.在构造方法中 进行成员变量的赋值,赋值后,可以拿到被装饰者的对象,可以调用被装饰者的方法;
3.对方法进行升级
例:模拟实现LineNumberReader
class MyLineNum{ // 装饰者类的特征 将被装饰者作为成员变量,可以是抽象类,也可以是接口 private Reader reader; // 用来标示行号 private int lineNumber = 0; // 无参构造没有意义,所以私有化无参构造 private MyLineNum() { super(); } public MyLineNum(Reader reader) { super(); this.reader = reader; } public int getLineNumber() { return lineNumber; } public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; } // 对read方法升级 public String myRead() throws IOException { // 每读一次,行号都应该多一 lineNumber++; // 用于将读取的字符拼接成字符串 StringBuilder sb = new StringBuilder(); int len = 0; while((len = reader.read()) != -1 ) { // 如果没有读到换行,就继续拼接,读到换行返回 if (len != '\n') { sb.append((char)len); }else { return sb.toString(); } } // 如果长度为0,说明读取已经结束 if (sb.length() == 0) { return null; } // 如果出循环,又不为空,说明读的是最后一行,返回 return sb.toString(); } public void myClose() throws IOException { reader.close(); } }
打印流
打印流永远不会抛出IO异常(其他异常依旧)。
操作的是输出目的,写文件,控制台打印
PrintStream(字节流)
构造方法:文件,字节输出流,路径。
PrintWriter(字符流)
构造方法:文件,字符输出流,路径,字节输出流。
打印流的核心功能:将要输出的流原样输出到目的端。
之前常用的System.out就是PrintStream对象。
打印流有自动刷新的功能,开对象声明时,在构造方法中传入true,就能开启自动刷新,自动刷新只对流有效。
例:使用System.in 来实现从控制台写入到文件中
FileOutputStream fos = new FileOutputStream(new File("输出路径")); InputStream in = System.in; // 用来拼接字符串 StringBuilder sb = new StringBuilder(); while (true) { // 从控制台读取输入 int read = in.read(); // 如果没有读到换行,说明一行没打完 if (read != '\n') { // 对字符进行拼接 sb.append((char)read); }else { // 读到了换行,将读取到的字符拼接后,转为字符串 // 给出循环出口条件 if (sb.toString().equals("quit")) { break; }else { // 将字符串写入文件 fos.write(sb.toString().getBytes()); sb.delete(0, sb.length()); } } }
合并流
SequenceInputStream
作用:可以把多个文件读成一个文件(合并成一个文件)
文件不局限于文本
两种构造方法:
// 将s1,s2读成一个文件,先s1,后s2 SequenceInputStream(InputStream s1, InputStream s2) // 将枚举器中的文件读成一个文件 SequenceInputStream(Enumeration<? extends InputStream> e)
例:如何实现对文件的分割
public static void msplit(File file) throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream(file); // 通过文件长度判断要分割成多少份 long length = file.length(); int count = (int) (length / (1024 * 1024)); double d = length % (1024 * 1024); if (d != 0) { count = count + 1; } // 读取文件 int len = 0; byte[] b = new byte[1024 * 1024]; // 根据分割的份数进行读取 for (int i = 0; i < count; i++) { // 将读取到的每一份文件分别写入文件中 File file2 = new File("/Users/lanou/Desktop/test/x/" + i + ".png"); FileOutputStream fos = new FileOutputStream(file2); len = fis.read(b); fos.write(b, 0, len); fos.close(); } fis.close(); }