装饰者模式
将原有的功能进行提升
装饰者模式的书写步骤
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();
}