一、导读
本文着重讲解java IO流如
InputStream ,OutputStream,Writer,Reader....
好文章 记得 收藏+点赞+关注 !!!
二、IO流简介
下图是一个描述输入流和输出流的类层次图:
Java IO即Java输入输出系统。
不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒介进行IO(文件、控制台、网络),我们还要考虑具体和它们的通信方式(顺序、随机、二进制、按字符、按字、按行等等)。
Java类库的设计者通过设计大量的类来攻克这些难题,这些类就位于java.io包中。
分类:
流按流向分为两种:输入流,输出流。
流按操作类型分为两种:
-
字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
-
字符流 : 字符流只能操作纯字符数据,比较方便。
区别:字节流每次读写一个字节,而字符流每次读写一个字符;
区分字符还是字节流:看类名结尾
例如:FileInputStream以Stream结尾的就是字节流,FileReader以Reader结尾的就是字符流
字节流的抽象父类:
-
InputStream
-
OutputStream
字符流的抽象父类:
-
Reader
-
Writer
三、字节流具体使用
1.FileInputStream 字节输入流
public class ByteStreamTest {
public static void main(String[] args) {
try {
//字节输入流
FileInputStream fileInputStream = new FileInputStream("D:\\carInfo.txt");
int b;
try {
while ((b = fileInputStream.read()) != -1) {
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();//将close放入到finally里 确保能关闭流,节省资源
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
运行结果:
注意:
这里可能有人就会问了,FileInputStream对象的read()方法返回的int数字到底是什么意思?
我:原来是这样,学到了学到了!
2.FileOutputStream 字节输出流
//字节输出流
FileOutputStream fos = new FileOutputStream("D:\\new.txt");//如果文件不存在,则会创建一个
//如果文件已存在,默认会清空再写入,想追加写入 可以按下面这种方式写入
//FileOutputStream fos = new FileOutputStream("D:\\new.txt",true);
fos.write(10);
fos.write("hello".getBytes(StandardCharsets.UTF_8));
fos.write("world".getBytes(StandardCharsets.UTF_8));
fos.close();
3.输出输入综合使用
public static void test() throws IOException {
FileInputStream fis = new FileInputStream("D:\\carInfo.txt");
FileOutputStream fos = new FileOutputStream("D:\\carInfoCopy.txt");
//定义一个数组,每次读入数组大小数据
byte[] bytes = new byte[1024];
//有效字节个数
int len;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
//释放流
fis.close();
fos.close();
}
4.BufferedInputStream&&BufferedOutputStream
缓冲思想:
字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多, 这是加入了数组这样的缓冲区效果,java本身在设计的时候,
也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
- BufferedInputStream
BufferedInputStream内置了一个缓冲区(数组) 从BufferedInputStream中读取一个字节时 BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个 程序再次读取时, 就不用找文件了, 直接从缓冲区中获取 直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个。
- BufferedOutputStream
BufferedOutputStream也内置了一个缓冲区(数组) 程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中 直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。
public static void test01() throws IOException {
FileInputStream fis = new FileInputStream("D:\\算法图解.pdf");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("D:\\算法图解copy.pdf");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int b;
while ((b = bis.read()) != -1) {
bos.write(b);
}
//flush()方法 用来刷新缓冲区的,刷新后可以再次写出
//只需要关闭装饰对象即可
bis.close();
bos.close();
}
四、字符流具体使用
字符流是可以直接读写字符的IO流
字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出.
1.FileReader
public static void test02() throws IOException {
FileReader fileReader = new FileReader("D:\\carInfo.txt");
int b;
while ((b=fileReader.read())!=-1){
//写出字符, 需要把字符转为字节再写出
System.out.print((char)b);
}
fileReader.close();
}
2.FileWriter
public static void test03() throws IOException {
FileWriter fileWriter = new FileWriter("D:\\carInfo.txt",true);
fileWriter.write("hello");
fileWriter.write("world");
fileWriter.close();
}
3.FileReader和FileWriter综合使用实现文件复制
private static void test04() throws IOException {
FileReader fr = new FileReader("D:\\new.txt");
FileWriter fw = new FileWriter("D:\\newCopy.txt");
int ch;
while((ch= fr.read())!=-1){
fw.write(ch);
}
fr.close();
fw.close();
}
4.BufferedWriter&&BufferedReader
- BufferedReader的
read()
方法读取字符时会一次读取若干字符到缓冲区, 然后逐个返回给程序, 降低读取文件的次数, 提高效率 - BufferedWriter的
write()
方法写出字符时会先写到缓冲区, 缓冲区写满时才会写到文件, 降低写文件的次数, 提高效率
private static void test05() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("D:\\new.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\newCopy.txt"));
int ch;
while ((ch = br.read()) != -1) {
bw.write(ch);
}
/**
String s;
//readLine()方法可以读取一行字符(不包含换行符号)
while((s = br.readLine())!=null){
bw.write(s);
//换行
bw.newLine();
}
**/
br.close();
bw.close();
}
五、字符流字节流的分别使用场景
- 字符流只能对文本文件进行读取, 它比字节流对文本文件的操作效率高。
- 字节流主要是对非文本文件(如一些媒体文件 :图片,电影,音乐等)进行操作的,字节流可以对所有类型的文件进行操作。
就先写这么多了,溜了溜了…