IO流
流的分类
按照流的操作单位分类:
1.字节流(8bit):就是处理0/1数据的,一般为图片、视频类、word文件
2.字符流(16bit):就是一个一个的char型数据,比如’a’,就是文本文件,就是我们平常能看懂的,比如txt文件
按照流的流向分类(是站在程序的角度来分析的)
1.输入流:从文件读取数据到程序(内存)中
2.输出流:从程序中写到文本文件中
按照流的角色分类
1.节点流:就是一个流
2.处理流:一般是在一个流的基础上再包一层或多层的流
流向 | 字节流 | 字符流 |
---|---|---|
流进 | InputStream | Reader |
流出 | OutStream | Writer |
流的体系结构:
抽象基类 | 节点流(文件流) | 缓冲流(处理流的一种) |
---|---|---|
InputStream | FileInputStream | BufferedInputSteam |
OutStream | FileOutStream | BufferedOutSteam |
Reader | FileReader | BufferedReader |
Writer | FileWriter | BufferedWriter |
注:抽象类回顾:①抽象类不能实例化②抽象类里面不一定有抽象方法③抽象方法一定在抽象类中④实体类继承抽象类一定要重写抽象方法⑥抽象类中可以有非抽象方法
文件读写操作步骤(节点流)
所有的文件操作都是基本一个套路
* 第一步:实例化我们要操作的文件 File fi=new File(路径);
* 第二步:实例化我们要用的哪种流(字节流/字符流)
* 字节流:FileInputStream fis=new FileInputStream(fi);
* 字符流: FileReader fr=new FileReader(fi);
* 第三步:读取操作
* 这里需要用一个数组或字符串来控制一次接收多大空间存储(例如:Byte[] buffer=new Byte[1024]
* 调用函数int len=fr.read(buffer),这里的含义是每次读取到的数据用buffer长度数组来接收
* len是返回每次实际读取到的数据,我们用一个while来循环接收
* 第四步:资源的关闭fr.close()
* 这里上面的所有操作需要用try-catch-finally来处理(快捷键ctr+shift+z),fr.close()关闭操作在finally
* 而且里面还需要一个try-catch操作
*
* 写操作也是一样
public class FileReaderWriterTest {
@Test
public void reader() {
FileReader fir=null;
try {
/**
* 文件路径的选择
* 如果是在方法中,这个文件需要创建在当前moudle下,就可以使用相对路径,如果不是创 *建在moudle下,
* 则需要使用绝对路径,如果是在main方法中被调用,则需要使用绝对路径
* */
File fi=new File("hello.txt");
fir=new FileReader(fi);
char[] buffer=new char[5];
int len;
while ((len=fir.read(buffer))!=-1){
System.out.println(buffer.toString());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fir.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void WriterTest(){
FileReader fr=null;
FileWriter fw=null;
try {
File frc=new File("hello.txt");
File destrc=new File("hello1.txt");
fr=new FileReader(frc);
fw=new FileWriter(destrc);
char[] buffer=new char[5];
int len;
while ((len=fr.read(buffer))!=-1){
fw.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fw!=null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
处理流的操作(eg.缓冲流Buffered**)
/**
* 处理流的操作就是多一个流,也就是在节点流的基础上多包一层流,比如缓冲流
* FileReader fr=new FileReader(srcfile);
* BufferedReader bfr=new BufferedReader(fr)
* 读取数据的时候用缓冲流来读取
* 关闭资源的时候我们先关闭外层流,再关闭内层流,但是一般情况下我们关闭了外层流,内层流也就自动
* 关闭了,所以我们一般只需要关闭外层流
* */
@Test
public void bufferedReaderWriterTest(){
BufferedReader bfr=null;
BufferedWriter bfw=null;
try {
FileReader fr=new FileReader(new File("hello.txt"));
FileWriter fw=new FileWriter(new File("hello3.txt"));
//缓冲流
bfr=new BufferedReader(fr);
bfw=new BufferedWriter(fw);
String data;
while ((data=bfr.readLine())!=null){
bfw.write(data);
bfw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bfr!=null){
try {
bfr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bfw!=null){
try {
bfw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
转换流
/**
* 转换流
* 从字节流转换为字符流,也就是解码操作 InputStreamReader()
* 从字符流转换为字节流,也就是编码操作 OutputStreamWriter()
* */
@Test
public void inputStreamReaderWriter(){
InputStreamReader bfr=null;
OutputStreamWriter bfw=null;
try {
FileInputStream fr=new FileInputStream(new File("hello.txt"));
FileOutputStream fw=new FileOutputStream(new File("hello3.txt"));
//缓冲流
bfr=new InputStreamReader(fr,"utf-8");
bfw=new OutputStreamWriter(fw,"gbk");
char[] cbuf=new char[20];
int len;
while ((len=bfr.read(cbuf))!=-1){
bfw.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bfr!=null){
try {
bfr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bfw!=null){
try {
bfw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}