目录
3.2、字节输出流 OutoutStream(写字节数据出去的)
一、IO流:概述
1、IO流概述
I表示intput,把硬盘文件中的数据读入到内存的过程,称之输入,负责读。
O表示output,把内存中的数据写出到硬盘文件的过程,称之输出,负责写。
2、IO流的分类
2.1、按流的方向分
2.2、按流中的数据最小单位分
3、总结流的四大类:
3.1、字节输入流 InputStream(读字节数据的)
字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流
称为字节输入流。
3.2、字节输出流 OutoutStream(写字节数据出去的)
字节输出流:以内存为基准,把内存中的数 据以字节写出到磁盘文件或者网络中去的流称为
字节输出流。
3.3、字符输入流 Reader(读字符数据的)
字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流
称为字符输入流。
3.4、字符输出流 Writer(写字符数据出去的)
字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流
称为字符输出流。
4、IO流的作用
用来读写文件数据的
二、IO流:字节流
1、字节输入流:每次读取一个字节
作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。
构造器:
构造器 | 说明 |
public FileInputStream(File file) | 创建字节输入流管道与源文件对象接通 |
public FileInputStream(String pathname) | 创建字节输入流管道与源文件路径接通 |
方法:
方法名称 | 说明 |
public int read() | 每次读取一个字节返回,如果字节已经没有可读的返回-1 |
缺点:
性能较慢
读取中文字符输出无法避免乱码问题。
2、字节输入流:每次读取一个字节数组
作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。
方法:
方法名称 | 说明 |
public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 |
缺点:
读取的性能得到了提升。
读取中文字符输出无法避免乱码问题。
注意:
1、使用字节流读取中文输出乱码,如何使用字节输入流读取中文输出不乱码呢?
定义一个与文件一样大的字节数组,一次性读取完文件的全部字节。
2、直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?
如果文件过大,字节数组可能引起内存溢出。
3、字节输入流:读取文件的全部字节
方式一:
自己定义一个字节数组与文件的大小一样大,然后使用读取字节数组的方法,一次性读取完成。
方法名称 | 说明 |
public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 |
方式二:
官方为字节输入流InputStream提供了如下API可以直接把文件的全部数据读取到一个字节数组中
方法名称 | 说明 |
public byte[] readAllBytes() throws IOException | 直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回 |
注意:
直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?
如果文件过大,字节数组可能引起内存溢出。
4、字节输出流:写字节数据到文件
作用:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去的流。
构造器:
构造器 | 说明 |
public FileOutputStream(File file) | 创建字节输出流管道与源文件对象接通 |
public FileOutputStream(File file,boolean append) | 创建字节输出流管道与源文件对象接通,可追加数据 |
public FileOutputStream(String filepath) | 创建字节输出流管道与源文件路径接通 |
public FileOutputStream(String filepath,boolean append) | 创建字节输出流管道与源文件路径接通,可追加数据 |
API方法:文件字节输出流(FileOutputStream)写数据出去的API
方法名称 | 说明 |
public void write(int a) | 写一个字节出去 |
public void write(byte[] buffer) | 写一个字节数组出去 |
public void write(byte[] buffer , int pos , int len) | 写一个字节数组的一部分出去。 |
流的关闭与刷新:
方法 | 说明 |
flush() | 刷新流,还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
5、文件拷贝
需求:
把某个视频复制到其他目录下的“b.avi”
分析:
根据数据源创建字节输入流对象
根据目的地创建字节输出流对象
读写数据,复制视频
释放资源
代码:
/**
目标:了解字节输出流
*/
public class OutputStreamDemo04 {
public static void main(String[] args) throws Exception {
//1、创建一个文件字节输出流管道与目标文件接通
// OutputStream os = new FileOutputStream("file-io-app/src/out04.txt");//先清空之前的数据,写新数据进入
OutputStream os = new FileOutputStream("file-io-app/src/out04.txt",true); //与之前的数据接通
//2、写数据出去
//a.public void write(int a):写一个字节出去
os.write('a');
os.write(98);
// os.write('王');
os.write("\r\n".getBytes());
//b.public void write(byte[] buffer):写一个字节数组出去。
byte[] butter = {'a', 98, 99, 105};
os.write(butter);
os.write("\r\n".getBytes());
byte[] butter2 = "我是中国人".getBytes();
// byte[] butter3 = "我是中国人".getBytes("GBK");
os.write(butter2);
// os.write(butter3);
os.write("\r\n".getBytes());
//c.public void write(byte[] buffer, int pos, int len):写一个字节数组的一部分出去
byte[] butter4 = {'a', 98, 99, 105};
os.write(butter4,0,3);
os.write("\r\n".getBytes());
// os.flush(); //写数据必须,刷新数据 可以继续使用流
os.close(); //释放资源,包含了刷新的!关闭后流不可以使用了
}
}
三、IO流:资源释放的方式
1、try-catch-finally
finally:放在try-catch后面的,无论是正常执行还是异常执行代码,最后一定要执行,除非JVM退出。
作用:一般用于进行最后的资源释放操作(专业级做法)
try-catch-finally格式:
/**
目标:TryCatchFinallyDemo
*/
public class TryCatchFinallyDemo1 {
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
//1、创建一个字节输入流管道与原视频接通
try {
// int c = 10/0;
is = new FileInputStream("file-io-app/src/out04.txt");
//2、创建一个字节输出流管道与目标文件接通
os = new FileOutputStream("file-io-app/src/out05.txt");
//3、定义一个字节数组转移数据
byte[] butter = new byte[1024];
int len; //记录每次读取字节数
while ((len = is.read(butter)) != -1 ){
os.write(butter,0,len);
}
System.out.println("复制完成!");
// int c = 10/0;
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("===========finally===========");
try {
//释放资源
os.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(sum(10, 2));
}
public static int sum(int a, int b){
try{
int c = a/b;
return c;
}catch (Exception e){
e.printStackTrace();
return -1; //计算出现BUG
}finally {
//哪怕上面有return语句执行,也必须先执行完这里才可以!
//开发中不建议在这里加return,如果加了,返回的永远是这里的数据,这样会出现问题!
return 100;
}
}
}
2、try-with-resource
finally虽然可以用于释放资源,但是释放资源的代码过于繁琐!
简化代码:
/**
目标:TryCatchResouceDemo
*/
public class TryCatchResouceDemo2 {
public static void main(String[] args) {
try(
//1、创建一个字节输入流管道与原视频接通
InputStream is = new FileInputStream("file-io-app/src/out04.txt");
//2、创建一个字节输出流管道与目标文件接通
OutputStream os = new FileOutputStream("file-io-app/src/out05.txt");
MyConnection mc = new MyConnection();
) {
//3、定义一个字节数组转移数据
byte[] butter = new byte[1024];
int len; //记录每次读取字节数
while ((len = is.read(butter)) != -1 ){
os.write(butter,0,len);
}
System.out.println("复制完成!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyConnection implements AutoCloseable{
@Override
public void close() throws Exception {
System.out.println("资源关闭!");
}
}