黑马程序员_学习笔记第19天——缓冲区、转换流、字节流
来源:互联网 发布:淘宝卖家在哪里看评价 编辑:程序博客网 时间:2024/05/22 01:57
1、BufferedWriter
缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前,必须要先有流对象。
该缓冲区中提供了一个跨平台的换行符:newLine();
public static void main(String[] args) throws IOException{//创建一个字符写入流对象FileWriter fw = new FileWriter("d:\\buf.txt");//为了提高字符写入流效率,加入了缓冲技术//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可BufferedWriter bufw = new BufferedWriter(fw);for(int x=0 ; x<5; x++) {bufw.write("abcd"+x);bufw.newLine();bufw.flush();//记住,只要用到缓冲区,就要记得刷新}//其实关闭缓冲区,就是在关闭缓冲区中的流对象bufw.close();}
2、字符读取流缓冲区BufferedReader
该缓冲区提供了一个一次读一行的方法readLine,方便于对文本数据的获取。当返回null时,表示读到文件末尾。
readLine方法返回的时候只返回回车符之前的数据内容,并不返回回车符。
readLine方法原理:无论是读一行,获取读取多个字符,其实最终都是在硬盘上一个一个读取,所以最终使用的还是read方法一次读一个的方法。
public static void main(String[] args) throws IOException{//创建一个读取流对象和文件相关联FileReader fr = new FileReader("d:\\buf.txt");//为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数BufferedReader bufr = new BufferedReader(fr);String line = null;while((line = bufr.readLine())!=null) {System.out.println(line);}bufr.close();}3、通过缓冲区复制一个.java文件
public class CopyTextByBuf {public static void main(String[] args) {BufferedReader bufr = null;BufferedWriter bufw = null;try {bufr = new BufferedReader(new FileReader("d:\\javatest\\Demo.java"));bufw = new BufferedWriter(new FileWriter("d:\\copy_Demo.txt"));String line = null;while((line= bufr.readLine())!=null) {bufw.write(line);bufw.newLine();bufw.flush();}}catch (IOException e ) {throw new RuntimeException("读写出错啦");}finally {try{if(bufr!=null)bufr.close();}catch (IOException e ) {throw new RuntimeException("读取关闭出错啦");}try{if(bufw!=null)bufw.close();}catch (IOException e ) {throw new RuntimeException("写入关闭出错啦");}}}}
4、自己编写readLine方法
class MyBufferedReader {private FileReader r ;MyBufferedReader(FileReader r) {this.r=r;}//可以一次读一行数据的方法public String myReadLine () throws IOException{//定义一个临时容器,原BufferedReader封装的是字符数组//为了演示方便,定义一个StringBuilder容器,因为最终还是要将数据变成字符串StringBuilder sb = new StringBuilder();int ch=0;while((ch=r.read())!=-1) {if(ch=='\r')continue;if(ch=='\n')return sb.toString();elsesb.append((char)ch);}if(sb.length()!=0)return sb.toString();return null;}public void myClose() throws IOException{r.close();}}
5、装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能,那么自定义的该类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
装饰模式比继承要灵活,避免了继承体系臃肿,而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能,所以装饰类和被装饰类通常都属于一个体系中的。
class MyBufferedReader extends Reader{private Reader r ;MyBufferedReader(Reader r) {this.r=r;}//可以一次读一行数据的方法public String myReadLine () throws IOException{//定义一个临时容器,原BufferedReader封装的是字符数组//为了演示方便,定义一个StringBuilder容器,因为最终还是要将数据变成字符串StringBuilder sb = new StringBuilder();int ch=0;while((ch=r.read())!=-1) {if(ch=='\r')continue;if(ch=='\n')return sb.toString();elsesb.append((char)ch);}if(sb.length()!=0)return sb.toString();return null;}public int read(char[] cbuf,int off,int len) throws IOException{return r.read(cbuf,off,len);}public void close() throws IOException{r.close();}}
6、LineNumberReader带行号的缓冲区
public static void main(String[] args) throws IOException{FileReader fr = new FileReader("d:\\buf.txt");LineNumberReader lnr = new LineNumberReader(fr);String line = null;lnr.setLineNumber(100);//行号从100开始while((line=lnr.readLine())!=null) {System.out.println(lnr.getLineNumber()+":"+line);}lnr.close();}
7、自己编写LineNumberReader
public class MyLineNumberReaderDemo {public static void main(String[] args) throws IOException{FileReader fr = new FileReader("d:\\buf.txt");MyLineNumberReader mlnr = new MyLineNumberReader(fr);String line = null;mlnr.mySetLineNumber(100);while((line=mlnr.myReadLine())!=null){System.out.println(mlnr.myGetLineNumber()+":"+line);}mlnr.close();}}class MyLineNumberReader extends MyBufferedReader {private int lineNumber;MyLineNumberReader(Reader r ) {super(r);}public String myReadLine() throws IOException{lineNumber++;return super.myReadLine();}public void mySetLineNumber(int lineNumber) {this.lineNumber = lineNumber;}public int myGetLineNumber() {return lineNumber;}}/*class MyLineNumberReader {private Reader r ;private int lineNumber;MyLineNumberReader(Reader r ) {this.r = r;}public String myReadLine() throws IOException{lineNumber++;StringBuilder sb = new StringBuilder();int ch = 0;while((ch=r.read())!=-1) {if(ch=='\r')continue;if(ch=='\n'){return sb.toString();}elsesb.append((char)ch);}if(sb.length()!=0)return sb.toString();return null;}public void mySetLineNumber(int lineNumber) {this.lineNumber = lineNumber;}public int myGetLineNumber() {return lineNumber;}public void myClose() throws IOException{r.close();}}*/
8、字节流
public static void readFile_3() throws IOException {FileInputStream fis = new FileInputStream("d:\\1.txt");byte[] b =new byte[fis.available()];//定义一个刚刚好的缓冲区,不用再循环了。但是要慎用,太大的文件会内存溢出fis.read(b);System.out.println(new String(b));fis.close();}public static void readFile_2() throws IOException {FileInputStream fis = new FileInputStream("d:\\1.txt");byte[] b =new byte[1024];int len = 0;while((len=fis.read(b))!=-1) {System.out.println(new String(b,0,len));}fis.close();}public static void readFile_1() throws IOException {FileInputStream fis = new FileInputStream("d:\\buf.txt");int ch = 0;while((ch=fis.read())!=-1) {System.out.print((char)ch);}fis.close();}public static void writeFile_1() throws IOException {FileOutputStream fos = new FileOutputStream("d:\\1.txt");fos.write("abcdefg".getBytes());fos.close();}9、练习:复制图片
/* 复制一个图片 思路:1、用字节读取流对象和图片关联2、用字符写入流对象创建一个图片文件,用于存储获取到的图片数据3、通过循环读写,完成数据的存储4、关闭资源*/public class CopyPicDemo {public static void main(String[] args) {FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream("c:\\1.jpg");fos = new FileOutputStream("c:\\2.jpg");byte[] buf = new byte[1024];int len=0 ;while((len=fis.read(buf))!=-1) {fos.write(buf,0,len);}}catch(IOException e ){throw new RuntimeException("读写异常");}finally {try {if(fis!=null)fis.close();}catch(IOException e) {throw new RuntimeException("读取异常");}try {if(fos!=null)fos.close();}catch(IOException e) {throw new RuntimeException("写入异常");}}}}
10、自定义BufferedInputStream
class MyBufferedInputStream {private InputStream in ;private byte[] buf = new byte[1024];private int pos =0,count = 0;MyBufferedInputStream(InputStream in) {this.in = in ;}//一次读一个字节,从缓冲区(字节数组)获取public int myRead() throws IOException{//通过in对象读取硬盘上数据,并存储buf中if(count==0) {count = in.read(buf);if(count<0)return -1;pos = 0;byte b = buf[pos];count--;pos++;return b&255;}else if (count>0) {byte b = buf[pos];count--;pos++;return b&0xff;}return -1;}public void myClose() throws IOException {in.close();}}11、读取键盘录入
System.out:对应的是标准输出设备,控制台
System.in:对应的标准输入设备:键盘
//键盘录入,读到“over”时停止public class ReadInDemo1 {public static void main(String[] args) throws IOException{//获取键盘录入对象//InputStream in = System.in;//将字节流对象转成字符流对象,使用转换流InputStreamReader,这是字节通向字符的桥梁//InputStreamReader isr = new InputStreamReader(in);//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader//BufferedReader bfr = new BufferedReader(isr);//键盘录入的最常见写法、BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));/*OutputStream out = System.out ;OutputStreamWriter osw = new OutputStreamWriter(out);BufferedWriter bfw = new BufferedWriter(osw);*/BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(System.out));String line =null;while((line=bfr.readLine())!=null) {if("over".equals(line))break;bfw.write(line.toUpperCase());bfw.newLine();bfw.flush();}bfr.close();/*StringBuilder sb = new StringBuilder();while(true) {int ch = in.read();if(ch=='\r')continue;if(ch=='\n') {String s = sb.toString();if("over".equals(s))break;System.out.println(s.toUpperCase());sb.delete(0,sb.length());}elsesb.append((char)ch);}*/}}
12、流操作的基本规律通过三个明确来完成
1)明确源和目的
源:输入流 InputStream Reader
目的:输出流 OutputStream Writer
2)操作的数据是否是纯文本
是:字符流
不是:字节流
3)当体系明确后,在明确要使用哪个具体的对象
通过设备来进行区分
源设备:内存,硬盘,键盘
目的设备:内存,硬盘,控制台
/*1、源:键盘录入目的:控制台2、需求:想把键盘录入的数据存储到一个文件中源:键盘目的:文件3、需求:想要将一个文件的数据打印在控制台上源:文件目的:控制台*/public class TransStreamDemo {public static void main(String[] args) throws IOException{BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("d:\\1.txt")));BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));//BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:\\3.txt")));String line = null;while((line=bufr.readLine())!=null) {if("over".equals(line))break;bufw.write(line.toUpperCase());bufw.newLine();bufw.flush();}bufr.close();bufw.close();}}
13、将一个文本文件中数据存储到另一个文件中,复制文件
1)
源:因为是源,所以使用读取流 InputStream Reader
是不是操作文本文件?是!这时就可以选择Reader。这样体系就明确了。
接下来明确要使用该体系中的哪个对象
明确设备:硬盘,上一个文件
Reader体系中可以操作文件的对象是FileReader
是否需要提高效率:是!加入Reader体系中缓冲区BufferedReader
FileReader fr = new FileReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);
2)
目的:OutputStream Writer
是否是纯文本?是!Writer
设备:硬盘,一个文件
Writer体系中可以操作文件的对象FileWriter
是否需要提高效率:是!加入Writer体系中缓冲区BufferedWriter
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferedWriter(fw);
14、将键盘录入的数据保存到一个文件中
1)
源:InputStream Reader
是否是纯文本文件?是,Reader
设备:键盘,对应的对象是System.in
需转成字符流按照字符串操作最方便。用Reader体系中转换流InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
需要提高效率吗?需要,BufferedReader
BufferedReader bufr = new BufferedReader(isr);
2)
目的:OutputStream Writer
是否是纯文本?是,Writer
设备:硬盘,一个文件,使用FileWriter
FileWriter fw = new FileWriter("c.txt");
需要提高效率吗?需要,BufferedWriter
BufferedWriter bufw = new BufferedWriter(fw);
15、扩展:想要把录入的数据按照指定的编码表(utf-8)将数据存到文件中
目的:OutputStream Writer
是否是纯文本?是,Writer
设备:硬盘,一个文件,使用FileWriter
但是FileWriter是使用的默认编码表GBK但是存储时,需要加入指定编码表utf-8,而指定的编码表只有转换流可以指定
所以要使用的对象是OutputStreamWriter
而该转换流对象要接收一个字节输出流,而且还可以操作文件的字节输出流,FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
需要高效吗?需要 BufferedWriter bufw = new BufferedWriter(osw);
所以,转换流是字符与字节之间的桥梁,通常,涉及到字符编码转换时,需要用到转换流。
16、System.setIn(new FileInputStream("1.txt"));//设置System.in由键盘录入改为1.txt的文件
System.setOut(new PrintStream("zzz.txt"));//设置System.out由控制台改为“zzz.txt”的文件
17、将异常信息存入日志文件中去
public static void main(String[] args) {try {int[] arr = new int[2];System.out.println(arr[3]);}catch(ArrayIndexOutOfBoundsException e) {try {Date d = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String s = sdf.format(d);PrintStream ps = new PrintStream("d:\\exception.log");ps.println(s);System.setOut(ps);}catch(IOException ex) {throw new RuntimeException("日志文件创建失败");}e.printStackTrace(System.out);}}
18、将系统信息存入到指定文件中去
public static void main(String[] args) throws IOException{Properties prop = System.getProperties();prop.list(new PrintStream("d:\\sysinfo.txt"));}
---------------------- ASP.Net+Android+IOS开发、href="http://edu.csdn.net"target="blank">.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
- 黑马程序员_学习笔记第19天——缓冲区、转换流、字节流
- 黑马程序员_学习笔记第18天——缓冲区、转换流、字节流
- 黑马程序员_IO流2_(字符缓冲区,字节缓冲区,字节字符转换流)
- 黑马程序员_学习笔记第19天——File类、递归、Properties、打印流
- 黑马程序员_自定义字节流的缓冲区
- 黑马程序员_字节流缓冲区入门讲解
- 黑马程序员——JAVA基础之IO流缓冲区,转换流,字节流
- 黑马程序员——IO(缓冲区、字节流、转换流、流操作规律)
- 黑马程序员——Java基础---IO(二)(缓冲区、字节流、流操作规律)--第19天--第226-247集
- 黑马程序员_学习笔记第18天——IO流、字符流
- 黑马程序员_学习笔记第21天——Object流、管道流、数据流
- 黑马程序员_学习笔记第17天——IO流、字符流
- 黑马程序员_学习笔记第20天——Object流、管道流、数据流
- 黑马程序员—字节流、自定义缓冲区、异常信息处理
- 黑马程序员_学习笔记第20天——File类、递归、Properties、打印流
- 黑马程序员_IO流二(字符缓冲区,字节缓冲区,字节字符转换流)
- 黑马程序员-字节流File读写操作_拷贝图片-mp3_自定义字节缓冲区
- 黑马程序员_基础_IO流学习笔记_字节流的学习
- 如何使作为主键的字段出现重复数据?
- 黑马程序员--配置path环境变量
- 浅谈C++模板,template method,strategy异同
- 在数据库中执行删除delete语句时出现:You are using safe update mode and you tried to update a table without a WHERE
- 一个简单的垃圾收集器实现
- 黑马程序员_学习笔记第19天——缓冲区、转换流、字节流
- 如何写出正确的二分查找?——利用循环不变式理解二分查找及其变体的正确性以及构造方式
- Android异步加载数据 AsyncTask demo application
- 关于一个统计个数的查询问题
- 日期时间型数据设置掩码
- Java中sleep()与wait()的区别
- 一个二维码扫描自动识别下载应用
- arp 地址解析协议
- 一个工作薄中有上百个工资表,如何统计每个工资表的总和?