字符流里面有自己的技术缓冲区,缓冲区的出现提高了对数据的读写效率。
字符流提供相应的缓冲区对象
BufferedWriter
BufferedRead
缓冲区的出现是为了提高流的操作效率而出现的
所以在创建缓冲区之前,必须要先有流对象
写入数据
class BufferedWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个字符写入流对象
FileWriter fw = new FileWriter("buf.txt");
//为了挺高字符写入流效率,加入了缓冲技术
//只要将流对象作为参数传递给 缓冲区的构造函数即可
BufferedWriter bufw= new BufferedWriter("fw");
bufw.writer("abcdef");
//只要用到了缓冲区,就要刷新
bufw.flush();
// 其实关闭缓冲区,就是在关闭缓冲区的流对象
bufw.close();
}
}
字符读取流缓冲区,该缓冲区提供了一个一次读一行的方法 readLine ,方便于对文本数据的获取
当返回null时,标识读到文件末尾。
class BufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
//创建一个读取流对象和文件相关联
FileReader fr = new FileReader("buf.txt");
//为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null)
{
System.out.println(line);
}
}
}
通过缓冲区复制文本文件 .java文件
class CopyTextByBuf
{
public void statci void(String[] args)
{
BufferedReader bufr = null;
BufferedWriter bufw =null;
try
{
bufr = new BufferedReader(new FileReader("BufferedWriter.java"));
bufw = new BufferedWriter(new FileWriter("BufferedWriter_Copy.txt"));
String line= null;
while((line=bufr.readLine)!=null)
{
bufw.writer(line);
bufw.newLine();
bufw.flush();
}
}catch(IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
try{
if(bufr!=null)
bufr.close();
}catch()
{
throw new RuntimeException("读取关闭失败");
}
try{
if(bufw!=null)
bufw.close();
}catch()
{
throw new RuntimeException("写入关闭失败");
}
}
}
}
装饰设计模式,就是假如别人写了一个类,我去接手,不用动他写的类里的方法,我自己再写个装饰类,把他写的类作为构造函数的入参传进来就可以了,如果我写的有问题,可以直接注释掉,继续用他写的类里的方法。
当想要对已有的对象进行功能增强时
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能
那么自定义的该类称为装饰类
装饰类通常会通过构造方法接收被装饰的对象
并基于被装饰的对象的功能,提供更强的功能
class Person
{
public void chifan()
{
System.out.println("吃饭");
}
}
class SuperPerson
{
private Person p;
SuperPerson(Person p)
{
this.p = p;
}
public void superChifan()
{
System.out.print("开胃酒");
p.chifan();
System.out.print("甜点");
System.out.print("来一根");
}
}
class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person();
SuperPerson sp = new SuperPerson();
sp.superChifan();
}
}
类LineNumberReader,带行号的
class LineNumberReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("PersonDemo.java");
LineNumberReader lnr = new LineNumberReader(fr);
String line =null;
lnr.setLineNumber(100);
while((line=lnr.readLine())!=null)
{
System.out.println(lnr.getLineNumber()+":"+line);
}
lnr.close();
}
}
字符流,操作文本
FileReader
FileWriter
BufferedReader
BufferedWriter
字节流
操作图片,想要操作图片数据,这时候就要用到字节流,字节流,不用刷新方法,但是也得用关闭资源方法。
OutputStream 是代表写,凡是输出的都是写
InputStream 是读
class FileStream
{
public static void main(String[] args)
{
writerFile();
}
//用字节流写入文件
public static void writerFile() throws IOException
{
FileOutputStream fos = new FileOutputStream("fos.txt");
fos.writer("abcdef".getBytes());
//不用刷新
fos.close();
}
//用字节流读取文件第一种方式
public static void readFile1() throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
int ch=0;
while((ch=fis.read())!=-1)
{
System.out.println((char)ch);
}
fis.close();
}
//用字节流读取文件第二种方式
public static void readFile2() throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
byte[] buf = new byte[1024];
int len= 0;
while((len=fis.read(buf))!=-1)
{
System.out.println( new String(buf,0,len));
}
fis.close();
}
//用字节流读取媒体文件第三种方式,字节流特有的,但是此方法如果 视频或者图片很多,可能会导
//致new的对象很大,内存溢出,jvm默认启动内存空间是64M,一般不用此方法
public statci void readFile3() throws IOExcepiton
{
FileInputStream fis = new FileInputStream("fos.txt");
byte[] buf = new byte[fis.available()];//定义一个刚刚好缓冲区,不用循环了
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
}
复制一个图片步骤
1、用字节流读取流对象和图片关联
2、用字节流写入流对象创建一个图片文件,用于存储获取到的图片数据
3、通过循环读写,完成数据的存储
4、关闭资源
字符流 只用来处理文字数据的,不能用来拷贝图片
class CopyPic
{
pubic static void main(String[] args)
{
try
{
FileOutputStream fos = null;
FileInputStream fis = null;
byte[] buf = new byte[1024];
int len =0;
while((len=fis.read(buf)!=-1)
{
fos.writer(buf,0,len);
}
}catch(IOException e)
{
throw new RuntimeException("复制图片异常");
}
finally
{
try
{
if(fos!=null)
{
fos.close();
}
}catch(IOException e)
{
throw new RuntimeException("写入图片异常");
}
try
{
if(fis!=null)
{
fis.close();
}
}catch(IOException e)
{
throw new RuntimeException("读取图片异常");
}
}
}
}
字节流的缓冲区
class CopyMp3
{
public static void main(String[] args)
{
long start= System.currentTimeMillis();
copy_1();
long end=System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
public static void copy_1() throws IOException
{
BufferedInputStream bufis = new BufferedInputStream(new
FileInputStream("c:\\0.mp3"));
BufferedOutputStream bufos =new BufferedOutputStream(new
FileOutStream("c:\\1.mp3"));
int by= 0;
while((by=bufis.read)!=-1)
{
bufos.writer(by);
}
bufis.close();
bufos.close();
}
}
读取键盘录入
class ReadIn
{
public static void main(String[] args)
{
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
while(true)
{
int ch =in.read();
if(ch=="\r")
continue;
if(ch=="\n")
{
String s = sb.toString();
if(s.equals(s))
{
break;
System.out.println(s.toUpperCase);
sb.delete(0,sb.length);
}
}
else
{
sb.append((char)ch);
}
}
}
}
刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理,也就是readLine方法
能不能直接用readLine方法来完成键盘录入的一行数据的读取呢
readLine方法是字符流BufferedReader类中的方法
而键盘录入的read方法是InputStream的方法
读取转换流
class TranStreamDemo
{
public static void main(String[] args)
{
//获取键盘录入对象
InputStream in = System.in;
//将字节流对象转成字符流对象,使用转化流
InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
bufr.close();
}
}
写入转换流
class TranStreamDemo
{
public static void main(String[] args)
{
//键盘录入,就用这句 最常见写法, 把字节流转成字符流,在加入到缓冲区
BufferedReader bufr = new BufferedReader (new InputStreamReader(System.in));
//
BufferedWriter bufw = new BufferedWriter(new OutStreamWriter(System.out));
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.writer(line.toUpperCase);
bufw.newLine();
bufw.flush();
}
}
}
1、源:键盘录入
目的:控制台
如上面的
2、需求,想把键盘录入的数据存储到文件中
源:键盘
目的:文件
class TransStreamDemo2
{
public static void main(String[] args)
{
//键盘输入
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//储存到文件里
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt") ));
String line = null;
while((line=bufr.readLine)!=null)
{
bufr.writer(line);
bufr.newLine()
bufr.flush();
bufr.close();
}
}
}
3、需求,把想要将一个文件的数据打印在控制台中
源:文件
目的:控制台
clase TransStreamDemo3
{
public static void main(String[] args)
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(FileInputStream("copy.txt")));
BufferedWtriter bufw = new BufferedWtriter(new OutputStreamWriter(System.out));
String line = null;
while((line=bufr.readLine)!=null)
{
bufr.writer(line);
bufr.newLine();
bufr.flush();
bufr.close();
}
}
}
流操作的基本规律
通过两个明确来完成
1、明确源和目的
源:输入流,InputStream Reader
目的:输出流,OutpuStream Writer
2、操作的数据是否是纯文本
是纯文本 字符流
不是纯文本,字节流
3、当体系明确后,在明确要使用哪个具体的对象
通过设备来进行区分,源设备包括,内存,硬盘,键盘
目的设备,内存,硬盘,控制台
举例,
1、将一个文本文件中数据存储到另一个文件中,复制文件
源:文件 InputStream Reader,因为是源所以使用的是读取流
是不是操作文本文件,是, 这时就可以选择Reader
这样体系就明确了, 接下来,明确要使用该体系中的哪个对象
明确设备,硬盘上的一个文件,Reader体系中,可以操作文件的对象是FileReader
FileReader fr = new FileReader("a.txt");
是否需要提高效率,加入Reader体系中缓冲区,BufferedReader
BufferedReader bufr = new BufferReader(fr);
目的:文件
OutputStream Writer
是纯文本, Writer
明确设备,硬盘,一个文件,可以操作文件的对象,FileWriter
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferWriter();
2、需求,将键盘录入的数据保存到一个文件中
源:InputStream Reader
是不是纯文本? 是Reader
设备:键盘,对应的对象是System.in
为了操作键盘的文本数据方便,转成字符流按照字符串操作是最方便的
所以既然明确了Reader,那么就将System.in 转成Reader
用了Reader体系中的流转换,InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
是否要提高效率,使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer
是否是存文本, 是Writer
设备:硬盘,一个文件,使用对象 FileWriter
FileWriter fw = new FileWriter("a.txt");
需要提高效率BufferedWriter();
BufferedWriter bufw = new BufferedWriter(fw);
class TransStreamDemo2
{
public static void main(String[] args)
{
//键盘录入的写法
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//
BufferedWriter bufw = new BufferedWriter(new OutpurStreamReader(new FileOutStream("d.txt")));
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.writer();
bufw.newLine();
bufw.flush();
bufw.close();
}
}
}