一.装饰者模式
1.装饰者模式不让类和类之间产生继承关系,对对象的原有功能进行升级.
2.书写步骤:
1).明确被装饰对象
2).将被装饰者对象通过构造方法传入装饰类(装饰类中肯定有一个成员变量就是被装饰的对象)
3).拥有被装饰对象相当于可以调用对象的所有方法,就可以对该方法进行升级
public class Day21 {
public static void main(String[] args) {
Student student = new Student();
NewOrientalStudent nos = new LOStudent(student);
nos.study();
}
}
//学习的接口
interface Study{
void study();
}
//学生类
class Student implements Study{
public void study() {
System.out.println("在校学习语文 数学");
}
}
//装饰类
class NewOrientalStudent implements Study{
//将被装饰者声明为成员变量
private Student student;
//提供构造方法
public NewOrientalStudent() {
}
public NewOrientalStudent(Student student) {
this.student = student;
}
//对方法进行升级
public void study() {
// 调用原有学习方法
student.study();
//装饰新功能
System.out.println("学习了开车");
}
}
二.lineNumberReader
1.lineNumberReader:跟踪行号的缓冲字符输入流
public class Day21 {
public static void main(String[] args) throws IOException{
//读取文件,带行号
FileReader fr = new FileReader("/Users/lanou/Desktop/test/hello.txt");
LineNumberReader lnr = new LineNumberReader(fr);
String string = null;
//设置默认行号
lnr.setLineNumber(100);
while ((string = lnr.readLine()) != null) {
//打印读取内容
System.out.println(lnr.getLineNumber() + ":" +string);
}
lnr.close();
// 模拟LineNumberReader类 利用装饰者模式 实现获取设置行号功能
//读取文件
FileReader fr = new FileReader("/Users/lanou/Desktop/test/hello.txt");
LineNumberReader lnr = new LineNumberReader(fr);
MyNumberReader myNumberReader = new MyNumberReader(lnr);
String string = null;
//打印读取出的文件
while ((string = myNumberReader.newReadLine()) != null) {
System.out.println(myNumberReader.getLineNumber() +":"+ string);
}
//关闭流
myNumberReader.myClose();
}
}
class MyNumberReader{
//被修饰对象
private Reader reader;
//行号设置为属性(提供set/get方法)
private int lineNumber = 0;保存行号
public MyNumberReader() {
super();
}
public MyNumberReader(Reader reader) {
super();
this.reader = reader;
}
public int getLineNumber() {
return lineNumber;
}
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
//升级 读行
public String newReadLine() throws IOException {
//读单个字符方法
//遇到/n 一行结束,使用拼接字符串将其返回
lineNumber++;
StringBuffer sb = new StringBuffer();
int len = 0;
while ((len = reader.read()) != -1) {
//读一行返回一行
if (len != '\n') {
//拼接字符
sb.append((char)len);
}else {
//返回拼接好的字符串
return sb.toString();
}
}
//循环不执行,表示文件读完
return null;
}
//关流
public void myClose() throws IOException{
reader.close();
}
}
三.打印流
1.分类:
PrintStream(字节流)
其构造方法可以传文件对象,字符串路径,字节流
PrintWriter(字符流)
其构造方法可以传文件对象,字符串路径,字节流,字符流
注意:只有操作流对象 才能自动刷新
2.特点:
1).不会抛出IO异常
2).原样输出到目的端
public class Demo08 {
public static void main(String[] args) {
//PrintWriter 字符流打印
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/test/hello.txt");
PrintWriter pw = new PrintWriter(fos, true);
pw.println("lisi");
pw.print(100);
pw.close();
//PrintStream字节流打印
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/test/hello.txt");
PrintStream ps = new PrintStream(fos);
ps.println("hahah");
ps.print(false);
ps.print(100);
}
}
练习:1利用System.in 从控制台接收,利用System.out 输出到控制台
输入quit 停止输入,打印到控制台(不用Scanner)
public class Day21 {
public static void main(String[] args) throws IOException {
System.out.println("请输入字母,以quit结束");
InputStream in = System.in;
int len = 0;
StringBuffer sb = new StringBuffer();
while (true) {
if (sb.toString().equals("quit")) {
break;
}
//读取
len = in.read();
//拼接字符串
if (len != '\n') {
//拼接
sb.append((char)len);
}else {
//输出
System.out.println(sb);
sb.delete(0, sb.length());
}
}
}
}
练习2:
从控制台输入文字 写到文件中(可以写中文)quit停止,使用 System.in利用转换流 高效流 打印流(原样输出 自动刷新)
public class Day21 {
public static void main(String[] args) throws IOException {
System.out.println("请输入内容");
InputStream in = System.in;
//使用转换流将字节转字符
InputStreamReader isr = new InputStreamReader(in);
//readLine()
BufferedReader br = new BufferedReader(isr);
//打印流原样输出
File file = new File("/Users/lanou/Desktop/test/hello.txt");
FileWriter fw = new FileWriter(file);
PrintWriter pw = new PrintWriter(fw, true);
String string = "";
int num = 0;//行号
//循环判断
while (true) {
num++;
if ((string = br.readLine()) != null) {
if (string.equals("quit")) {
break;
}
pw.println(num +":"+ string);
}
}
br.close();
pw.close();
}
}
四.合并流
1.合并流(SequenceInputStream)是字节流,任何类型的文件都可合并
2.作用:可以将多个文件合并成新的文件
public class Demo08 {
public static void main(String[] args) throws IOException{
//合并两个文件
File file1 = new File("/Users/lanou/Desktop/test/t1.txt");
File file2 = new File("/Users/lanou/Desktop/test/t2.txt");
File file3 = new File("/Users/lanou/Desktop/test/t3.txt");
FileInputStream fis1 = new FileInputStream(file1);
FileInputStream fis2 = new FileInputStream(file2);
FileInputStream fis3 = new FileInputStream(file3);
//创建合并流
SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
//写入到新的文件中
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/test/4.txt");
int len = 0;
while ((len = sis.read()) != -1) {
fos.write(len);
}
sis.close();
fos.close();
//合并三个文件,使用打印流写入
//创建字节流并且将三个流添加到集合中
Vector<FileInputStream> vector = new Vector<>();
vector.add(new FileInputStream(file1));
vector.add(new FileInputStream(file2));
vector.add(new FileInputStream(file3));
//获取迭代器
Enumeration<FileInputStream> elements = vector.elements();
//合并文件
SequenceInputStream sis = new SequenceInputStream(elements);
//使用打印流写入
InputStreamReader isr = new InputStreamReader(sis);
BufferedReader br = new BufferedReader(isr);
FileWriter fw = new FileWriter("/Users/lanou/Desktop/test/5.txt");
PrintWriter pw = new PrintWriter(fw, true);
String string = null;
while ((string = br.readLine()) != null) {
pw.write(string);
}
br.close();
pw.close();
}
}
练习3:
分割:
将1张文件 分割成多个文件每个文件按1M分割 1024*1024
读取文件 一次读1M,将这1M 写到一个新的文件中分割完后
合并:
再将分割的多个文件合并成一个文件
//分割
public class Demo08 {
public static void main(String[] args) throws IOException{
File file = new File("/Users/lanou/Desktop/test/命.mp3");
FileInputStream fis = new FileInputStream(file);
byte[] b = new byte[1024 * 1024];
int len = 0;
int name = 0;//分割文件名
//读取写入
while ((len = fis.read(b)) != -1) {
name++;
File tempFile = new File("/Users/lanou/Desktop/test/music/" +"命"+ name +".MP3");
FileOutputStream fos = new FileOutputStream(tempFile);
fos.write(b, 0, len);
//关流
fos.close();
}
fis.close();
//合并
Vector<FileInputStream> vector = new Vector<>();
for (int i = 1; i <= 11; i++) {
File file = new File("/Users/lanou/Desktop/test/music/命" + i + ".MP3");
//添加到集合中
vector.add(new FileInputStream(file));
}
//获取迭代器
Enumeration<FileInputStream> elements = vector.elements();
//合并文件
SequenceInputStream sis = new SequenceInputStream(elements);
//写入
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/test/music/命命.mp3");
byte[] b = new byte[1024 * 1024];
int len = 0;
while ((len = sis.read(b)) != -1) {
fos.write(b, 0, len);
}
sis.close();
fos.close();
}
}
五.commons-io
public class Day21 {
public static void main(String[] args) throws IOException{
//FilenameUtils 类方法 操作文件名
//获取路径扩展名
String extension = FilenameUtils.getExtension("/Users/lanou/Desktop/test/music/命命.mp3");
System.out.println(extension);
//获取文件的名字
String name = FilenameUtils.getName("/Users/lanou/Desktop/test/music/命命.mp3");
System.out.println(name);
//判断是不是这个扩展名
boolean b = FilenameUtils.isExtension("/Users/lanou/Desktop/test/music/命命.mp3", "mp3");
System.out.println(b);
//FileUtils类中方法 操作文件
//复制文件 将源文件复制到目标文件夹中
File srcFile = new File("/Users/lanou/Desktop/Test/hello.txt");
File destDir = new File("/Users/lanou/Desktop/heihei");
FileUtils.copyFileToDirectory(srcFile, destDir);
//复制文件 将源文件复制到目标文件中
File destFile = new File("/Users/lanou/Desktop/heihei/hell.txt");
FileUtils.copyFile(srcFile, destFile);
//IOUtils类中方法 操作流
//写入字符串到文件
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/heihei/hell.txt");
IOUtils.write("你好啊", fos);
//读取文件
FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/heihei/hell.txt");
byte[] b = new byte[1024];
int read = IOUtils.read(fis, b);
//读取文件到集合中以字符串形式
List<String> readLines = IOUtils.readLines(fis);
System.out.println(readLines);
}
}