缓冲区的实现
//建立缓冲流对象
class MyBufferReader extends Reader {
private Reader r; //持有一个流对象
//因为是缓冲对象,内部必须有数组存放数据
private char[] chars = new char[1024];
private int index = 0; //定义角标
private int count = 0;
public MyBufferReader(Reader r) { //该缓冲对象一建立就必须有 被缓冲的对象
this.r = r;
}
public int read() throws IOException {
if (count == 0) { //一开始数组中个数为0,判断数组中是否有元素
count = r.read(chars); //通过 被缓冲流对象 的read(char[])方法,往 缓冲区 数组中添加元素
index = 0; //从角标0开始读取
}
if (count < 0) {
return -1;
}
char ch = chars[index]; //从角标0开始读取
count--; //读取了一个数据,数组数量就减一
index++; //角标+1 继续读取下一位
return ch;
}
public String readLine() throws IOException {
//定义一个容器存储String
StringBuilder sb = new StringBuilder();
int ch = 0;
while ((ch = read()) != -1) { //读取字符数据
//存储前判断终止符
if (ch == '\r') {
continue;
}
if (ch == '\n') {
return sb.toString(); //读到终止符就返回容器字符串
}
sb.append((char) ch); //字符数据存入容器
}
//如果没有终止符
if (sb.length()!=0){
return sb.toString();
}
return null; //读到-1了就返回null
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
return r.read(cbuf);
}
@Override
public void close() throws IOException {
r.close();
}
装饰设计模式(功能对象)
public class Main {
public static void main(String[] args) {
FileReader f=new FileReader();
BufferReader br=new BufferReader(f);
br.read();
}
}
//例如 IO 中 Reader 体系
class Reader {
public void read() {
System.out.println("读取数据");
}
}
class FileReader extends Reader {
public void read() {
System.out.println("FileReaer.读取数据");
}
}
//为了使读取数据更高效,建立缓冲区类来对 FileReader进行装饰
class BufferReader extends Reader {
private Reader r;
public BufferReader(Reader r) { //该类一装饰类初始化就必须具备被装饰的类
this.r = r;
}
public void read() {
System.out.println("缓冲区技术加持");
r.read(); //依旧使用 被修饰类 读取的方式
}
}
Properties
特点:
- Hashtable的子类,map集合中的方法都可以用
- 该集合没有泛型,键值都是字符串
- 它是一个可以持久化的属性集,键值可以存到集合中,也可以存到持久化设备上,
键值来源也可以是持久化设备上
Properties基本使用
//将集合的数据持久化存到设备上;
public static void methoddemo1() throws IOException {
Properties ppt = new Properties();
ppt.setProperty("张三", "20");
ppt.setProperty("李四", "21");
ppt.setProperty("aa", "30");
//定义输出流对象
FileOutputStream fos = new FileOutputStream("E:\\aaa.properties");
OutputStreamWriter osw = new OutputStreamWriter(fos);
ppt.store(osw, "my demo");
osw.close();
// Set<String> set = ppt.stringPropertyNames();
// for (String s : set) {
// String value = ppt.getProperty(s);
// System.out.println(s + " : " + value);
// }
}
//加载设备的数据
public static void methoddemo2() throws IOException {
Properties ppt = new Properties();
//定义输入对象
FileReader fr = new FileReader("E:\\aaa.properties");
ppt.load(fr); //将输入的数据存到集合中
ppt.list(System.out); //打印一下看看
ppt.setProperty("张三", "19");
//定义输出流对象
FileOutputStream fos = new FileOutputStream("E:\\aaa.properties");
OutputStreamWriter osw = new OutputStreamWriter(fos);
ppt.store(osw, "set");
osw.close();
fr.close();
}
Properties 记录程序运行次数
//创建一个计数配置文件,记录程序运行次数
public static boolean checkCount() throws IOException {
boolean isrun = true; //标记
int count = 0; //定义次数
//将配置文件封装成对象
File file = new File("E:\\count.properties");
if (!file.exists()) {
file.createNewFile(); //如果不存在就创建
}
FileReader fr = new FileReader(file); //创建输入流对象
Properties prop = new Properties();
prop.load(fr); //读取文件数据,加载到集合中
String value = prop.getProperty("运行次数");
if (value != null) {
count = Integer.parseInt(value);//如果value不为空,则返回value的Integer形式
}
count++; //次数+1
if (count > 5) { //判断次数如果大于5,则返回fales
return isrun = false;
}
prop.setProperty("运行次数", String.valueOf(count)); //将最新数据重新写入集合中
FileWriter fw = new FileWriter(file); //定义输出流
prop.store(fw, "aa"); //将集合中的数据写入配置文件
fr.close(); //关闭流
fw.close();
return isrun; //返回true
}
public static void run() throws IOException {
//判断配置文件是否超过次数
if (!checkCount()) {
throw new RuntimeException("试用次数已过,请注册");
}
System.out.println("文件运行");
}