javaseday21(缓冲区 为什么弄个int 和 char[] readLine 的实现原理 如何自己实现)

来源:互联网 发布:杀敌算法百度云 编辑:程序博客网 时间:2024/06/05 09:44

缓冲区是提高效率 的没有对象 不能提高

本身就是封装了数组的对象 要有流对象

/*
 * 将一个c盘的文本文件 复制到d盘
 * 分析
 * 复制原理
 * 读取c盘文件中的数据
 * 将这些数据写入到d盘当中
 * 连读带写
 * 思路:
 * 1、需要读取源
 * 2、将读取到的源数据写到目的地
 */


public class IODemo01 {
public static void main(String[] args) throws IOException {
//1、读取一个已有的文本文件 使用字符读取流 和文件相关联
FileReader fr = new FileReader("demo.txt");//在eclipse中是项目目录
//2、创建一个目的 用于存储读到的数据
FileWriter fw = new FileWriter("copy.txt");
//3、频繁的读写操作
int  ch = 0;
while((ch = fr.read())!=-1) {//读取一般挂while循环
fw.write(ch); //记事本也有解析功能不然看到的内容不同
}
fw.flush();

fw.close();
fr.close();
//4、关闭资源
}
}

private static final int BUFFER_SIZE = 4096;// 一般都为1024的倍数 定义为常量提高效率


public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;


try {
fr = new FileReader("demo.txt");
fw = new FileWriter("copy2.txt");
// 创建一个临时容器,用于缓存读取到的字符
char[] buf = new char[BUFFER_SIZE];
// 定义一个变量记录读取到的字符数(其实就是往数组里装的字符个数)
int len = 0;
while ((len = fr.read(buf)) != -1) {
fw.write(buf, 0, len);// 有几个写几个
}


} catch (FileNotFoundException e) {


e.printStackTrace();
} catch (IOException e) {


throw new RuntimeException("读取失败");
} finally {
if (fw != null) {// 不能一起关闭 要依个判断 不然出错
try {
fw.close();
} catch (IOException e) {


e.printStackTrace();
}
}
if (fr != null) {
try {
fr.close();
} catch (IOException e) {


e.printStackTrace();
}
}
}
}


/*
 * 缓冲区的出现提高了对数据的读写效率
 * 对应类
 * BufferedReader BufferedWriter
 * 提高效率 把缓冲区进行了封装成对象
 * 缓冲区要结合流才可以使用
 * 在流的基础上对流的功能进行了增强
 * 做代码有2部分优化 
 * 1、设计优化 
 * 对代码重构 重新构建代码 让代码实现更强的扩展性灵活性以及复用性 可以用很多设计模式来完成
 * 2、性能优化
 * 提高性能的最常用的方法之一就是缓冲区
 * 缓冲区 不局限于BufferReader 概念很大  
 * 每次创建 每次销毁 麻烦  一次性创建10个 放在缓冲区 容器中  要用的时候直接拿用完放回
 * 省去了创建的麻烦   
 * 数据库的连接池就是其中一个运用 
 */




/*
 * BufferedWriter
 * 提供了newLine()方法 就是系统line.separator
 *
 */
public class IODemo04 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("demo01.txt");


//为了提高写入的效率 使用了字符流的缓冲区
//创建了一个字符写入流的缓冲区对象 并和指定要被缓冲的流对象关联


BufferedWriter bw = new BufferedWriter(fw);


//使用缓冲区的写入方法 将数据先写入到缓冲区中
// bw.write("ssdsaw");
// bw.newLine();//只在BufferedWriter找到有newLine() 不一定其他的也能用 可以自己弄个方法 也可以自己定义个常量
// bw.write("dds");
for (int i = 0; i < 5; i++) {
bw.write("ss"+i);
bw.newLine();
bw.flush();//写一个刷一次
}
//使用缓冲区的刷新方法将数据刷到目的地
bw.flush();
//关闭缓冲区
bw.close();//缓冲区 关闭 的时候流也被关闭了缓冲区只是封装了数组 提高了流中数据的操作效率
// fw.write("ss");//没有调用底层的资源 真正调用系统底层资源的是FileWriter 关缓存区其实关的就是fw
}
// public void close(){
// fw.close();
// }
}


/*
 * 根据回车符来判断 有几行
 * 字符流缓冲区
 * BufferedWriter
 * newLine()
 * BufferedReader
 * readLine();
 */
public class IODemo05 {
public static void main(String[] args) throws IOException {


// demo01();
FileReader fr = new FileReader("demo01.txt");


BufferedReader br = new BufferedReader(fr);
String line = null;
while((line = br.readLine())!=null){
System.out.println(line);
}
/*String line1 = br.readLine();
System.out.println(line1);
String line2 = br.readLine();
System.out.println(line2);
String line3 = br.readLine();
System.out.println(line3);
String line4 = br.readLine();//如果有行 但是没任何内容 就返回空白一片 不返回null
System.out.println(line4);
String line5 = br.readLine();
System.out.println(line5);*/
br.close();
}


public static void demo01() throws FileNotFoundException, IOException {
FileReader fr = new FileReader("demo01.txt");


char[] ch= new char[1024];
int len = 0;
while((len=fr.read(ch))!=-1){
System.out.println(new String(ch, 0, len));
}
fr.close();
}
}






public static void main(String[] args) throws IOException {


FileReader fr = new FileReader("demo01.txt");


BufferedReader br = new BufferedReader(fr);


FileWriter fw = new FileWriter("copy03.txt");
BufferedWriter bw = new BufferedWriter(fw);


String line = null;
while((line = br.readLine())!=null){//按照行读的时候因为是字符串了而且如果没有返回的是null所以用null来判断
bw.write(line);
bw.newLine();
bw.flush();
}


// int ch = 0;
// while((ch=br.read())!=-1){//比较原始 用缓冲提供的方法更强大
// bw.write(ch);
// }


br.close();
bw.close();
}


 /*
 * 自定义的读取缓冲区 其实就是模拟一个BufferedReader
 *
 * 分析
 * 缓冲区中无非就是封装了一个数组
 * 并对外提供了更多的方法对数组进行访问
 * 其实这些方法最终操作的都是数组的角标
 * 缓冲的原理
 * 其实就是从源中获取一批数据装进缓冲区中
 * 再从缓冲区不断的取出一个一个数据
 * 当此次取完后 再从源中继续取一批数据进缓冲区
 * 当源中的数据取光后 用-1作为结束标记
 */
public class MyBufferedReader {
private FileReader r;


//定义一个数组作为缓冲区
private char[] buf = new char[1024];
//定义一个指针用于操作这个数组中的元素 当操作到最后一个元素后 指针应该归零
private int pos = 0;


//定义一个计数器 用于记录缓冲区中的数据个数 当该数据减到0 就从源中继续获取数据到缓冲区中
private int count = 0;
public MyBufferedReader(FileReader r) {
this.r = r;
}


public int myRead() throws IOException{ //让对方try
if(count==0){
count = r.read(buf);
pos = 0;
}
if(count<0)
return -1;
char ch = buf[pos];
pos++;
count--;
return ch;
/*//1、从源中获取一批数据到缓冲区中 需要先做判断 只有计数器为0时才需要从源中获取数据
if(count==0){
count = r.read(buf);
if(count<-1)
return -1;
//每次获取数据到缓冲区后 角标归零
pos = 0;
char ch  = buf[pos];
pos++;
count--;
return ch;
}else if(count>0){
char ch = buf[pos];
pos++;
count--;
return ch;
}
//2
//3
*/ }


public String myReadLine() throws IOException{


StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=r.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;


}


public void myClose() throws IOException{//关的是被缓存的对象调用他自己的关闭方法就行
r.close();
}
}



阅读全文
0 0
原创粉丝点击