今天来扒扒关于IO流一章中字符流、字节流与转换流的关系
话不多说,首先上图,让你一眼对这个三角关系有个简单认知:
IO流:Input,Output,
流:类似于水流,线性的,有方向的;
分类:
字节流:
输出流:
输入流:
字符流:
输出流:
输入流:
什么情况下使用哪种流:
1.字节流:读写二进制文件:图片、视频文件等;也可以读写文本文件;
2.字符流:读写文本文件的;
Java中IO流的体系结构:
字节流:
输出流:OutputStream(抽象)
输入流:InputStream(抽象)
字符流:
输出流:Writer:(抽象)
输入流:Reader:(抽象)
简单的需求:向文件写入一个字符串:hello
分析:
1.向文件写入–>输出流–>OutputStream
2.向"文件"写,OutputStream是抽象类,不能用。使用它的子类:FileOutputStream
3.了解一下FileOutputStream
构造方法:
1.public FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流。
2.public FileOutputStream(File file):创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
public class Demo {
public static void main(String[] args) {
try {
//如果文件不存在,就自动创建一个空文件;
//使用的绝对路径
// FileOutputStream out = new FileOutputStream("D:\\FileTest.txt");
//使用相对路径;在项目根目录下
// FileOutputStream out2 = new FileOutputStream("FileTest.txt");
//使用File
File file = new File("D:\\FileTest.txt");
FileOutputStream out3 = new FileOutputStream(file);
File file2 = new File("FileTest2.txt");
FileOutputStream out4 = new FileOutputStream(file2);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
复制文件操作可同时涉及到字节输入输出流的问题
(1).一次读入一个字节的复制文件操作
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
思路:
1.复制:读取一个文件的内容,然后向另一个文件写入;
2.读取:FileInputStream — a.txt
一次读一个字节
写入:FileOutputStream — b.txt
一次写入一个字节
public class Demo {
public static void main(String[] args) {
try {
//输入流:文件必须存在;
FileInputStream in = new FileInputStream("a.txt");
//准备一个输出流:文件可以不存在
FileOutputStream out = new FileOutputStream("b.txt");
//开始复制:
//输入流:一次读取一个字节
//输出流:一次写入一个字节
int n = 0;
while((n = in.read())!= -1){
out.write(n);
}
//是否资源
in.close();
out.close();
System.out.println("复制完毕!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
(2).一次读入一个字节数组的复制文件操作
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
- 复制视频文件:一次读取、写入一个字节数组
- 速度明显快于一次读取一个字节;
*/
public class Demo {
public static void main(String[] args) {
try {
FileInputStream in = new FileInputStream("Big Fish.mp4");
//输出流
FileOutputStream out = new FileOutputStream("Big Fish_copy.mp4");
//开始复制:一次读取写入一个字节数组
byte[] byteArray = new byte[2048];
int len = 0;
while((len = in.read(byteArray))!= -1){
//写入
out.write(byteArray, 0, len);
}
//释放资源
in.close();
out.close();
System.out.println("复制完毕!");
}catch (IOException e) {
e.printStackTrace();
}
}
}
通过一次读取一个字节数组,大家体验到了字节数组对于读取效率的影响。
这里的字节数组就相当于一个"缓存区"
在Java类库中,为我们提供了字节读写的带缓存区的类:
输入流:BufferedInputStream
输出流:BufferedOutputStream:
(1)…缓冲区输入流:BufferedInputStream
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
- 构造方法:
- public BufferedInputStream(InputStream in):
- 对于BufferedInputStream和BufferedOutputStream的使用
- 同FileInputStream和FileOutputStream的使用是一样的。没有新增其它的方法;
- 但是:效率要高很多;
- 所以,对于字节的输入、输出流,推荐使用:BufferedInputStream和BufferedOutputStream
*/
public class Demo {
public static void main(String[] args) {
try {
BufferedInputStream in = new BufferedInputStream(
new FileInputStream("buf.txt"));
byte[] byteArray = new byte[1024];
int len = 0;
while((len = in.read(byteArray)) != -1){
System.out.println(new String(byteArray,0,len));
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(2).缓冲区输出流:BufferedOutputStream:
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
- 构造方法:
- 1.public BufferedOutputStream(OutputStream out):使用一个OutputStream来构造;
- 实际上还是由FileOutputStream提供输出流,BufferedOutputStream提供了缓冲区;
*/
public class Demo {
public static void main(String[] args) {
//1.构造一个对象
try {
/*FileOutputStream fileOut = new FileOutputStream("buf.txt");
BufferedOutputStream out = new BufferedOutputStream(fileOut);*/
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream("buf.txt"));
out.write("hello".getBytes());
//带缓冲区的输出流,write()之后,一定要flush()或close(),才能将缓冲区的内如写入文件;
// out.flush();
out.close();
//先执行自己的flush()方法,再执行OutputStream的close()方法
}
catch (IOException e) {
e.printStackTrace();
}
}
}