IO
1,IO就是在不同数据的传递。
2,IO分类:
1,流向:
输入流 读取数据
输出流 写出数据
2,数据类型:
字符流:
输入流 Reader
输出流 Writer
字节流:
输入流 InputStream
输出流 OutputStream
注意事项:
1,四个顶层类都是抽象类。
2, 一般每个体系的名称都是以基类为后缀。
应用场景:
文本文件使用字符流,一般情况下任意文件类型都可以使用字节流。
3,字符流
1,体系
Reader
|---InputStreamReader
|---FileReader
|---BufferedReader
Writer
|---OutPutStreamWriter
|---FileWriter
|---BufferedWriter
2,字符流复制文本的5种方法示例:
一次读写一个字符//FilerReader/FileWriter FileReader fr=new FileReader("c:\\a.txt"); FileWriter fw=new FileWriter("d:\\b.txt"); int ch=0; while((ch=fr.read())!=-1){ fw.write(ch); } fw.close(); fr.close();
一次读写一个字符数组//FileReader/FileWriter FileReader fr=new FileReader("c:\\a.txt"); FileWriter fw=new FileWriter("d:\\b.txt"); int len=0; char[] chs=new char[1024]; while((len=fr.read(chs))!=-1){ fw.wirte(chs,0,len); } fw.close(); fr.close();
缓冲流一次读写一个字符//BufferedReader/BufferedWriter BufferedReader br=new BufferedReader(new FileReader("c:\\a.txt")); BufferedWriter bw=new BufferedWriter(new FileWriter("d:\\b.txt")); int ch=0; while((ch=br.read())!=-1){ bw.write(ch); } bw.close(); br.close();
缓冲流一次读写一个字符数组//BufferedReader/BufferedWriter BufferedReader br=new BufferedReader(new FileReader("c:\\a.txt")); BufferedWriter bw=new BufferedWriter(new FileWriter("d:\\b.txt")); char[] chs=new char[1024]; int len=0; while((len=br.read(chs))!=-1){ bw.wirte(chs,0,len); } bw.close(); br.close();
缓冲流一次读写一行//BufferedReader/BufferedWriter BufferedReader br=new BufferedReader(new FileReader("c:\\a.txt")); BufferedWriter bw=new BufferedWriter(new FileWriter("d:\\b.txt")) String line=null; while((line=br.readLine())!=null){ bw.wirte(line); bw.newLine(); bw.flush(); } bw.close(); br.close();
4,字节流
字节流可以实现复制任何类型的数据。
体系:
InputStream
|---FileInputSream
|---BufferedInputStream
OutputStream
|---FileOutputSream
|---BufferedOutputStream
2,字节流复制文件的4种方式
字节流一次读写一个字节//FileInputStream/FileOutputStream FileInputStream fis=new FileInputStream("c:\\a.jpg"); FileOutputStream fos=new FileOutputStream("d:\\b.jpg"); int by=0; while((by=fis.read())!=-1){ fos.write(by); } fos.close(); fis.close();
字节流一次读写一个字节数组//FileInputSream/FileOutputSream FileInputSream fis=new FileInputStream("c:\\a.jpg"); FileOutputSream fos=new FileOutputSream("d:\\b.jpg"); byte[] bys=new byte[1024]; int len=0; whiel((len=fis.read(bys))!=-1){ fos.wirte(bys,0,len); } fos.close(); fis.close();
5,转换流
1,public static final InputSream in 是一个标准的键盘输入流。
因为我们输入的是字符,而它返回的是InputSream 是字节流,如果需要对这个进行封装的时候是有问题的。
字符缓冲流对象是只能对字符流进行高效包装,也就是说,它只针对字符流有效。
而现在返回的是字节流,但是又需要使用这个功能,怎么办?
如果有一个能把字节流转换成字符流实现就好了。
对此,Java提供了一个转换流。
InputStreamReader:是字节流通过字符流的桥梁。
InputStreamReader(InputSream in)
//这两种方法等价 InputStream is=System.in; InputSreamReader isr=new InputStreamReader(is); BufferedReader br=new BufferedReader(isr); //简化版 BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
示例:
对输入的文字进行保存
//转换流的简易示例 BufferedReader br=new BufferedReader(new InputSreamReader(System.in)); BufferedWriter bw=new BufferedWriter(new FileWriter("c:\\save.txt")); String line=null; while((line=br.readLine())!=null){ if("886".equals(line)){ break; } bw.write(line); bw.newLine(); bw.flush(); } bw.close(); br.close();
2, 需求:我要把一个文本文件的内容输出到控制台。
public static final PrintStream out 标准输出流。
通过分析:
OutputStream
|---FilterOutputStream
|---PrintStream
把一个文本文件的内容输出到控制台//简易示例 BufferedReader br=new BufferedReader(new FileReader(c:\\a.txt)); //OutputStream os=System.out; //OutputStreamWriter osw=new OutputStreamWriter(os); //BufferedWriter bw=new BufferedWriter(osw); //等价于↓ BurreredWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); String line=null; while((lin=br.readLine())!=null){ bw.write(line); bw.newLine(); bw.flush(); } bw.close(); br.close();
6,几个小问题:
1,文件不存在,会创建一个。文件如果存在,到底是重新创建,还是把内容给清空?
清空。
2,为什么要使用flush()?
使用的字符流,而底层是字节流,1字符=2字节,它不能不数据直接写到文本文件,其实是写到了数据缓冲区里面,所以需要调用flush()方法。
3,为什么要用close()?
1,把流对象标记为垃圾。
2,通知系统,释放和该文件相关的资源。
4,创建字符输出流,做了哪几件事?
1,第一次会通过系统管理去创建一个文件,以后会根据构造方法的第二个参数true或false来决定追加还是重写。
2,创建一个字符输出流对象。
3,把流对象指向文件。
5,close()与flush()的区别?
close():刷新缓冲区,释放资源,关闭流对象,流对象不能继续使用。
fluse():刷新缓冲区,流对象还可以继续使用。
6,怎么实现换行?
windows:\r\n
linux:\n
mac:\r
7,怎么实现追加内容?
FileWriter(String filename,boolean append),根据构造方法的第二个参数,true或false来追加或不追加。
7,字符编码
1,编码表:
字符及其对应的一张表。
2,常见的字符集:
ASCII
ISO-8859-1
GB2312
GBK
GB18030
BIG5
UTF-8
3,编码应用:
在IO流中如果想使用指定的编码读写数据,只能使用转换流。
OutputStreamWriter(OutputStream out, String charsetName)
OutputStreamWriter = out + charsetName
字符流 = 字节流 + 编码表
8,IO案例
需求:将d:\java目录下的后缀名.java文件 复制到e:\jad目录下,并把后缀名改为.jad
复制文件并修改名称/** * 封装目录获取源路径 * 获取该目录下的所有File数组,加过滤器 * 遍历File数组,获取每一个File对象 * 复制文件 */ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; public class RenName { public static void main(String[] args) throws IOException{ File srcFile=new File("d:\\java"); File[] fileArray=srcFile.listFiles(new FilenameFilter(){ public boolean accept(File dir,String name){ return new File(dir,name).isFile()&&name.endsWith(".java"); } }); File destFile=new File("e:\\jad"); if(!destFile.exists()){ destFile.mkdir(); } for(File file: fileArray){ String oldName=file.getName(); String newName=oldName.replace(".java",".jad"); File newFile=new File(destFile,newName); BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(newFile)); int len=0; byte[] bys=new byte[1024]; while((len=bis.read(bys))!=-1){ bos.write(bys,0,len); } bos.close(); bis.close(); } } }