-----<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
IO流学习-2
缓冲区的出现是为了提高流的操作效率而出现的
所以在创建缓冲区之前,首先要有流对象。
该缓冲区中提供了一个跨平台的换行符--》newLine();
import java.io.*;
public class test1 {
public static void main(String[] args) throws IOException
{
//创建一个字符写入流对象
FileWriter fw = new FileWriter("buf.txt");
//为了提高字符写入流效率,加入了缓冲技术。
//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter bf =new BufferedWriter(fw);
for (int i = 0; i < 5; i++) {
bf.write("abcde"+i);
bf.newLine();
bf.flush();
}
bf.close();
//记住只要到缓冲区,就要记得刷新。
//其实关闭缓冲区,就是在关闭缓冲区中的流对象。
/**
字符读取流缓冲区
该缓冲区提供了一个一次读一行的方法,readLine,方便与对文本数据的获取
当返回值为null 时表示读到文件尾部。
* */
//创建一个读取流对象文件和文件相关联。
FileReader fr = new FileReader("buf.txt");
//为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数。
BufferedReader bfr = new BufferedReader(fr);
String line =null;
while((line = bfr.readLine())!= null)
System.out.println(line);
bfr.close();
}
}
----------
练习
通过缓冲区,复制一个.java文件
readline方法原理
无论是读一行还是获取多个字符
其实最终都是在硬盘上一个一个读取,所以
最终还是read方法一次一次读一个的方法。
import java.io.*;
public class test2 {
public static void main(String[] args) throws IOException
{
BufferedWriter bfw = null;
BufferedReader bfr = null;
try {
bfw =new BufferedWriter(new FileWriter("buff.txt"));
bfr = new BufferedReader(new FileReader("IO1.txt"));
String line =null;
while((line = bfr.readLine())!= null)
{
bfw.write(line);
bfw.newLine();
bfw.flush();
}
} catch (IOException e) {
}
finally
{
if(bfr !=null)
try {
bfr.close();
} catch (IOException e2) {
}
if(bfw !=null)
try {
bfw.close();
} catch (IOException e2) {
}
}
}
}
-----------------
import java.io.FileReader;
import java.io.IOException;
明白了bufferedreader类中特有方法readlin的原理后
可以自己定义一个类中包含一个功能和readline一直的方法
来模拟一下bufferedreader
----
装饰设计模式
当想要对已有的对象进行功能增强时,
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
那么定义的该类称为装饰类。
装饰类通常会通过构造方法接受被装饰的对象,
并基于被装饰的对象的功能,提供更强的功能。
装饰模式比继承更要零活,避免了继承体系臃肿
而且降低了类与类之间的关系
装饰类因为增强已有对象,具备的功能和已有的是相同的。
只不过提供了更强功能,所以装饰类和被装饰类通通常属于一个体系中。
public class test3 {
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("buf.txt");
mybf bf = new mybf(fr);
String line = null;
while((line = bf.myr()) != null)
{
System.out.println(line);
}
bf.myc();
}
}
class mybf
{
private FileReader r;
mybf(FileReader r)
{
this.r =r;
}
//可以一次读取一行数据方法。
public String myr()throws IOException
{
//定义一个临时ring器,原bufferreader封装的是字符数组。
//为了方便,定义一个stringbuilder容器,最终还是要将数组变成字符串。
StringBuilder sb =new StringBuilder();
int ch =0;
while((ch =r.read())!= -1)
{
if(ch =='\r')
continue;
if(ch== '\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length() !=0)
return sb.toString();
return null;
}
public void myc()throws IOException
{
r.close();
}
}
--------------------
字符流:
FileReader
FileWriter
BufferedReader
BufferedWriter
字节流:
InputStream
OutputStream
需求:想要操作图片,这是就要用到字节流。
import java.io.*;
public class test4
{
public static void readFile3()throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
int num = fis.available();
//定义一个刚刚好的缓冲区,不用循环。
byte[] buf = new byte[fis.available()];
fis.read(buf);
System.out.println(new String(buf));
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();
}
public static void readFile()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 writeFile()throws IOException
{
FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write("adfbsdf".getBytes());
fos.close();
}
public static void main(String[] args) throws IOException
{
// writeFile();
// readFile();
// readFile2();
readFile3();
}
}
---------------
package IO2;
//MP3的复制 通过缓冲区
import java.io.*;
public class test5 {
public static void main(String[] args) throws IOException
{
long start =System.currentTimeMillis();
copy();
long end = System.currentTimeMillis();
System.out.println(end-start);
}
public static void copy() throws IOException
{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("g:\\500394cnwav.mp3"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\1.mp3"));
int by = 0;
while((by =bis.read())!= -1)
{
bos.write(by);
}
bis.close();
bos.close();
}
}
---------------------
import java.io.FileInputStream;
import java.io.FileOutputStream;
复制一个图片
思路:用字节读取流对象和图片关联
用字节写入流对象创建一个图片文件,用于存储获取到的图片数据
通过循环读写,完成数据的存储。
关闭资源。
import java.io.*;
import javax.management.RuntimeErrorException;
public class test6 {
public static void main(String[] args)throws IOException
{
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("CHUCUO");
}
finally
{
try {
if(fis !=null)
fis.close();
} catch (Exception e) {
throw new RuntimeException("CHUCUO");
}
try {
if(fos !=null)
fos.close();
} catch (Exception e) {
throw new RuntimeException("CHUCUO");
}
}
}
}
-----------------
读取键盘录入
需求:
通过键盘录入数据
当录入一行数据后,就将该行数据进行打印,
如果录入的数据是over,那么停止录入。
通过刚才的键盘录入一行数据并打印其大写,
发现其实就是读一行数据的原理。
也就是readline方法
能不能直接使用readline 方法来完成键盘录入的一行数据读取呢?
readline 方法是字符流bufferedreader类中的方法
而键盘录入的read方法是字节流InputStream的方法。
能不能将字节流转换成字符流使用
import java.io.*;
public class test7 {
public static void main(String[] args) throws IOException
{
// OutputStream out = System.out;
// OutputStreamWriter osw = new OutputStreamWriter(out);
// BufferedWriter bfw = new BufferedWriter(osw);
//上面三条语句简化成下面语句:
//标准键盘输入语句:重要。
BufferedWriter bfw =
new BufferedWriter(new OutputStreamWriter(System.out));
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line =br.readLine()) !=null)
{
if("over".equals(line))
break;
bfw.write(line.toUpperCase());
bfw.newLine();
bfw.flush();
}
bfw.close();
br.close();
//获取键盘录入对象
//InputStream in =System.in;
//将字节流对象 转换成字符流对象,使用转换流,InputStreamReader
//InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高新操作,使用bufferedreader
//BufferedReader br = new BufferedReader(isr);
//可以将上面三条语句简化成:
/*BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line =br.readLine()) !=null)
{
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
br.close();*/
/*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("over".equals(s))
break;
System.out.println(s.toUpperCase());
sb.delete(0, sb.length());
}
else
sb.append((char)ch);
}*/
//读一个打印一个
// InputStream in =System.in;
// int ch =0;
// while((ch =in.read())!=-1)
// {
// System.out.println(ch);
// }
//获取键盘输入
// InputStream in =System.in;
// int by = in.read();
// System.out.println(by);
}
}
----------------
流操作的基本规律
最痛苦的就是流对象有很多,不知道该用哪一个。
通过三个明确:
1.明确源和目的:
源:输入流 inputstream reader
目的:输出流 outpurstream writer
2.操作的数据是否是纯文本
是: 字符流。
不是:字节流。
3.
当体系明确后,在明确要使用哪个具体的对象
通过设备来进行区分
源设备:内存,硬盘,键盘。
目的设备:内存 , 硬盘 , 控制台
1-将一个文本文件数据存储到另一个文件中,复制文件。
源----inputstream reader 因为是源,所以使用读取流。
是不是操作文本文件 是--》reader 不是--》inputstream
体系明确了
结下来明确对象:
明确设备--硬盘,上的文件。
reader体系中可以操作,文件的对象是FileReader。
FileReader fr =new FileReader("a.txt");
是否要提高效率。
是--》加入reader体系中的缓冲区BufferedReader。
BufferedReader bufr = new BufferedReader(fr);
目的--outputstream writer
是否纯文本
是--》writer
设备:硬盘,一个文件
writer 体系中可以操作文件的对象FileWriter
FileWriter fw =new FileWriter("b.txt");
是否要提高效率。
是--》加入reader体系中的缓冲区BufferedWriter。
BufferedWriter bw = new BufferedWriter(fw);
-------------------
2.需求,将键盘录入数据保存一个文件中
这个需求中有源和目的都存在
源:Inputstream reader
是不是纯文本 是 reader
设备:键盘 对应的对象是system.in;
不是选择reader吗?system.in对应的不是字节流吗?
为了操作键盘文件数据的方便,转成字符流按照字符串操作时最方便的
所以既然明确了reader,那么就将system.in转换成reader
用了reader体系中的转换流InputStreamReader
InputStreamReader isr = new InputStreamReader(system.in);
需要提高效率吗 需要 BufferedReader(isr);
BufferedReader bufr = new BufferedReader(isr);
目的:outputstream writer
是否纯文本 是 writer
设备 硬盘 一个文件 使用filewriter
FileWriter fw =new FileWriter("c.txt");
需要提高效率吗 需要
BufferedWriter bw = new BufferedWriter(fw);
扩展一下,想把录入的数据按照指定的编码表,将数据存入文件中。
目的:outputstream writer
是否纯文本 是 writer
设备 硬盘 一个文件 使用filewriter
但是存储时,需要加入指定编码表,而指定编码表只有转换流可以指定
所以要使用的对象是outputstreamwriter
而该转换流对象要接受一个字节输出流,,而且还可以操作文件的字节输出流FileOutStream
OutputStreamWriter osw =new OutputStreamWriter(new FileOutStream("d.txt"),"UTF-8");
需要高效吗 需要
BufferedWriter bw = new BufferedWriter(osw);
所以记住,转换流。字符和字节之间的桥梁,通常涉及到字符编码转换时
需要用到转换流。
1.源,键盘输入
目的控制台
public class test8 {
public static void main(String[] args) throws IOException
{
BufferedWriter bfw =
new BufferedWriter(new OutputStreamWriter(System.out));
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line =br.readLine()) !=null)
{
if("over".equals(line))
break;
bfw.write(line.toUpperCase());
bfw.newLine();
bfw.flush();
}
bfw.close();
br.close();
}
}
2.需求,想把键盘录入数据存储到一个文件中。
源,键盘输入
目的,文件
public class test8 {
public static void main(String[] args) throws IOException
{
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bfw =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt")));
String line = null;
while((line =br.readLine()) !=null)
{
if("over".equals(line))
break;
bfw.write(line.toUpperCase());
bfw.newLine();
bfw.flush();
}
bfw.close();
br.close();
}
}
3.需求想将一个文件数据打印在控制台上
源,文件
目的,控制台
import java.io.*;
public class test8 {
public static void main(String[] args) throws IOException
{
BufferedReader br =
new BufferedReader(new InputStreamReader(new FileInputStream("IO1.txt")));
BufferedWriter bfw =
new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line =br.readLine()) !=null)
{
if("over".equals(line))
break;
bfw.write(line.toUpperCase());
bfw.newLine();
bfw.flush();
}
bfw.close();
br.close();
}
}
打印系统日志。
public static void main(String[] args)throws IOException
{
Prpperties prop = System.getProperties();
//System.out.println(prop);
prop.list(new PrintStream("sysinf.txt"));
}
打印异常日志
import java.util.*;
import java.io.*;
import java.text.*;
import javax.swing.text.SimpleAttributeSet;
public class test9 {
public static void main(String[] args) {
try {
int [] arr =new int[2];
System.out.println(arr[3]);
} catch (Exception e) {
try {
Date d =new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
String s = sdf.format(d);
PrintStream ps =new PrintStream("exception.log");
ps.println(s);
System.setOut(ps);
} catch (IOException e2) {
throw new RuntimeException("日志文件创建失败");
}
e.printStackTrace(System.out);
}
}
}
-----<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------