java之LineNumberReader类,装饰者模式,打印流,合并流(文件合并和分割)和第三方工具类(IO的)

一.LineNumberReader类

public class Kll {
	public static void main(String[] args) throws IOException {
	        File file = new File("/Users/lanou/Desktop/Test/happy.txt");
		FileReader in = new FileReader(file);
		LineNumberReader lReader = new LineNumberReader(in);
		String string = null;
		// 设置行号(默认从1开始)
		lReader.setLineNumber(100);
		while ((string = lReader.readLine()) != null) {
			System.out.println(lReader.getLineNumber() + ":" + string);
		}
		lReader.close();
	}
}

二.装饰者类

  • 装饰者模式(解耦 不让类与类产生继承的关系)

    • 对 对象的原有功能进行升级
  • 书写步骤:

    • 1.明确被装饰的对象.
    • 2.将被装饰的对象,通过构造方法传入装饰类
      • 装饰类中肯定有一个成员变量,就是被装饰对象
    • 3.拥有被装饰的对象,相当于可以调用该对象中的所有方法
      • 就可以对该方法进行升级
1.需求:	利用装饰类完成                
	在校学生类 学习java,js,c++
	去培训机构提升知识学习 H5
// 学习接口
interface Study{
	void study();
}
// 在校学生类
class Student implements Study{

	@Override
	public void study() {
		System.out.println("在校学生 学了c++,java,js");
	}
}
// 包装自己,即装饰类
class LoStudent implements Study{
	// 将被装饰者声明为成员变量
	private Student student;

	// 提供有参构造方法
	public LoStudent() {
		super();
		// TODO Auto-generated constructor stub
	}
	public LoStudent(Student student) {
		super();
		this.student = student;
	}
	
	// 对方法进行升级
	@Override
	public void study() {
		// 调原有学生学习方法
		student.study();
		// 装饰新功能
		System.out.println("蓝鸥进修学习H5");
	}
}
public class Kll {
	public static void main(String[] args) {
		Student student = new Student();
		LoStudent student1 = new LoStudent(student);
		student1.study();
	}
}
2.需求:利用装饰者模式完成
	// 模拟LineNumberReader类 利用装饰者模式 实现获取设置行号功能
	// 被装饰的对象是Reader类
	// 要装饰的方法 单个字符读取---->升级 能读行
	// 在方法中添加记录行号功能
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

// 模拟LineNumberReader类
class MyLineNumberReader{
	// 被装饰对象
	private FileReader fr;
	// 行号 声明属相
	private int lineNumber;
	// 构造方法
	public MyLineNumberReader() {
		super();
	}
	public MyLineNumberReader(FileReader fr) {
		super();
		this.fr = fr;
	}
	// set/get方法
	public int getLineNumber() {
		return lineNumber;
	}
	public void setLineNumber(int lineNumber) {
		this.lineNumber = lineNumber;
	}
	
	// 功能升级 读行升级
	public String newReaderLin() throws IOException {
		// 用到Reader中 读单个字符的方法
		// 遇到\n 一行就结束了
		// 使用拼接字符串将这行返回
		
		// 设置行号
		this.lineNumber++;
		int len = 0;
		StringBuffer sb = new StringBuffer();
		while ((len = fr.read()) != -1) {
			// 读一行返回一行
			if (len != '\n') {
				// 拼接字符
				sb.append((char)len);
			}else {
				// 直接返回拼好的字符串
				return sb.toString();
			}
			
		}
		// 循环不执行,文件就读完了 返回null
		return null;
	}
	
	// 提供关流的方法
	public void clo() throws IOException {
		fr.close();
	}
	
}
public class Kll {
	public static void main(String[] args) throws IOException {
		
		// 模拟LineNumberReader类 利用装饰者模式 实现获取设置行号功能
		// 被装饰的对象是Reader类
		// 要装饰的方法 单个字符读取---->升级 能读行
		// 在方法中添加记录行号功能
		
		File file = new File("/Users/lanou/Desktop/Test/happy.txt");
		FileReader in = new FileReader(file);
		MyLineNumberReader mlnr = new MyLineNumberReader(in);
		String string = null;
		mlnr.setLineNumber(12);
		while ((string = mlnr.newReaderLin()) != null) {
			System.out.println(mlnr.getLineNumber() + ":" + string);
		}
		mlnr.clo();
	}
}

三.打印流

public class Kll{
	public static void main(String[] args) throws IOException {
	// 打印流(用字节流)写文件
	       FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/new.txt");
		PrintStream ps = new PrintStream(fos);
		// 写文件
		ps.println("kll");
		ps.print(false);
		ps.print(100);
		ps.close();

	// 打印流(用字符流写文件)
		FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/new.txt");
		PrintWriter pw = new PrintWriter(fos, true);
		pw.println("分割");
		pw.println(100);
		pw.println(true);
		pw.close();
	}
}

需求:

  • 利用System.in 从控制台就收
  • 利用System.out 输出到控制台
  • 输入quit 停止输入
  • 打印到控制台(不用Scanner)
    代码如下:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
/*
 * 利用System.in 从控制台就收
 * 利用System.out 输出到控制台
 * 输入quit 停止输入
 * 打印到控制台(不用Scanner)
 */
// 卡住程序的 .read()方法
public class Kll {
	public static void main(String[] args) throws IOException {
		//fun1();
		//fun2();
		
		System.out.println("请输入:");
		InputStream in = System.in;
		// 拼接字符串
		StringBuffer sb = new StringBuffer();
		while (true) {
			// 读
			int read = in.read();
			// 没换行进行拼接
			if ((char)read != '\n') {
				sb.append((char)read);
				// 循环的结束条件
			}else {
				// 直接输出到控制台
				System.out.println(sb);
				// 清空sb字符串
				sb.delete(0, sb.length());
			}if (sb.toString().equals("quit")) {
					break;
			}
			
		}
	}
}

四.合并流

字节流 任何文件都可以合并

第一种构造方法:两个字节流做参数

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

public class Demo05 {
	public static void main(String[] args) throws IOException {
	
		// 合并两个文件
		File f1 = new File("/Users/lanou/Desktop/Test11/new.txt");
		File f2 = new File("/Users/lanou/Desktop/Test11/kll.txt");
		FileInputStream fis1 = new FileInputStream(f1);
		FileInputStream fis2 = new FileInputStream(f2);
		 // 创建合并流
		SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
		// 写入到新的文件中  打印流写
		FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/Long.txt");
		// 读写
		int len = 0;
		while ((len = sis.read()) != -1) {
			fos.write(len);
		}
		sis.close();
		fos.close();
	}
}

第二种构造方法:以Vector集合作为参数

public class Kll{
	public static void main(String[] args) throws IOException {
	        // 合并三个文件 要求使用打印流写入
		// 将要合并的文件的三个流 添加到Vector集合中
		
		File f1 = new File("/Users/lanou/Desktop/Test11/new.txt");
		File f2 = new File("/Users/lanou/Desktop/Test11/kll.txt");
		File f3= new File("/Users/lanou/Desktop/Test11/Long.txt");
		// 创建字节流 并且将三个流添加到集合中
		// 创建集合
		Vector<FileInputStream> vector = new Vector<>();
		vector.add(new FileInputStream(f1));
		vector.add(new FileInputStream(f2));
		vector.add(new FileInputStream(f3));
		// 获取迭代器(枚举器)
		Enumeration<FileInputStream> elements = vector.elements();
		SequenceInputStream sis = new SequenceInputStream(elements);
		
		// 打印流写入 
		// 转换流 转成 bufferReader
		InputStreamReader isr = new InputStreamReader(sis);
		BufferedReader br = new BufferedReader(isr);
		// 写的
		FileWriter fw = new FileWriter("/Users/lanou/Desktop/Test11/Short.txt");
		// 打印流
		PrintWriter pw = new PrintWriter(fw, true);
		String str = null;
		while ((str = br.readLine()) != null) {
			// 写
			pw.println(str);
		}
		pw.close();
		br.close();
	}
}

文件的切割和合并
需求:

  • 将1张图片 分割成多个文件
  • 每个文件按1M分割 1024*1024
  • 读取图片 一次读1M
  • 将这1M 写到一个新的文件中
  • 分割完后
  • 再将分割的多个文件合并成一个图片
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

public class Kll {
	public static void main(String[] args) throws IOException {
		// 切割方法调用
		fun1();
		// 构建装好的vector集合
		Vector<FileInputStream> vector = new Vector<>();
		for (int i = 1; i < 12; i++) {
			File file = new File("/Users/lanou/Desktop/Test11/歌曲" +  i + ".mp3");
			vector.addElement(new FileInputStream(file));
		}	
		
		// 获取枚举器
		Enumeration<FileInputStream> elements = vector.elements();
		// 创建合并流
		SequenceInputStream sis = new SequenceInputStream(elements);
		
		// 写出
		//File file = new File("/Users/lanou/Desktop/Test11/music.mp3");
		
		FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/music.mp3");
		int len = 0;
		byte[] bs = new byte[1024];
		while ((len = sis.read(bs)) != -1) {
			fos.write(bs, 0, len);
		}
		fos.close();
		sis.close();
	}

	public static void fun1() throws FileNotFoundException, IOException {
		// 切割文件 1M保存为一个文件
		// 读入流
		FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/Test11/歌曲.mp3");
		// 声明数组
		byte[] b = new byte[1024 * 1024];
		// 声明循环变量 分割的文件名
		int num = 0;
		// 字节有效长度
		int len = 0;
		while ((len = fis.read(b)) != -1) {
			// 文件名序号加加
			num++;
			// 创建写的文件流
			FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/歌曲" +  num + ".mp3");
			// 写入的有效长度
			fos.write(b, 0, len);
			// 关闭流(写一个关一个)
			fos.close();
		}
		fis.close();
	}
}

五.第三方工具类

 * commons-io-2.4 操作流的第三方工具
 * commons-io-2.4.jar 是倒入工程包
 * commons-io-2.4-sources 方法的源码

* FilenameUtils
 * 获取路径扩展名
 * static String getExtension(String filename)
 * 获取文件的名字
 * static String getName(String filename)
 * 判断是不是这个扩展名
 * static boolean isExtension(String filename,String extension)
 * 
 * FileUtils类中
 * 复制文件夹
 * static void copyDirectoryToDirectory(File src,File desc)
 * 复制文件
 * static void copyFile(File src,File desc)
 * 
 * IOUtils类中
 * 写入字符串到文件
 * static void writeStringToFile(File src,String date)
 * 读取文件按字符串
 * static String readFileToString(File src)
 * 
 * 写入文件 可以选取用什么字节流写入
 * static void write(String data, OutputStream output)
 * 读取文件到集合中以字符串形式
 * static List<String> readLines(InputStream input)

猜你喜欢

转载自blog.csdn.net/KongLingLei_08225/article/details/82747581