IO 字节流 字符流 高效缓冲流 close()flush()区别
这篇也是纯课堂笔记,没做什么总结和编辑,都是理解性的内容,直接流的概念和怎么用就行
IO
input和output 输入和输出, 用于设备与设备进行交互,数据从其他设备进入到内存就是输入,从内存把数据写到其他设备中称之为输出
IO的分类
四类都是抽象类,定义字节流和字符流操作的公共方法
IO程序书写流程
-
导包: IO包
-
操作流对象时会有异常,需处理
-
操作完流对象要关闭流资源
InputStream
字节输入流的顶层父类
是一个抽象类,不能创建对象,只能由子类创建
常用方法:
-
close() 关闭流资源,释放资源
-
read() 获取一个字节数据
-
read(byte[] b) 从当前流对象,读取数据存储到数组b中
字节流
-
可以直接操作字节信息的流对象
-
根据流向输入流和输出流
FileInputStream
是字节输入流的一个子类,用于磁盘上的文件交互 是原始字节的图像数据流
一次读取一个或多个字节的内容,图片,音乐视频都可
构造方法:
-
FileInputStream(File file) :读取file文件中的数据
-
FileInputStream(String path):读取path路径所代表的文件
无论你使用哪个构造方法,都只能封装文件的路径,不能封装文件夹
常用方法:
-
read():一次读取一个字节,返回int类型,每读取一个字节后指向位置会自动向后偏移一个字节,如果已读到末尾,会返回-1,即获取到-1就表示读取结束
-
read(byte[] b):一次读取多个字节,把字节存储到数组b中,返回中代表向b数组存储的字节个数,如返回值是-1,说明读取文件结束
package Inp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Inpu {
public static void main(String[] args) throws IOException {
File file = new File("11.txt");
FileInputStream fis = new FileInputStream(file);
int len = 0;
byte[] i = new byte[1024];//b数组的长度,一般是1024,或是1024的整数倍,目的是为了减少IO的次数
while ((len = fis.read(i))!=-1) {
System.out.println(new String(i,0,len));
}
}
}
OutputStream
1、字节输出流的顶层父类
2、常用方法:
-
close() 关闭流对象
-
flush() 将缓冲区的内容刷新到文件中
-
write() 一次写出一个字节
-
write(byte[] b) 一次写出一个b数组的内容
-
write(byte[] b,int offset, int len) 一次性从b数组指定位置offset开始,写出len个元素
FileOutputStream
可以写出纯文本的内容,也可以写出图像,音乐,视频
构造方法:
(1) FileOutputStream(File f):字节输出流,把数据写到file文件中去
(2) FileOutputStream(String path):把数据写到path路径所描述文件中
(3) FileOutputStream(String|File parm ,boolean append):表示是否要在指定文件中把输入内容拼接到目标文件中,append =true 是拼接,false就是覆盖
常用的对象方法
-
close()
-
write()
-
write(byte[] b)
-
write(byte[] b,int offset,int len)
文件拷贝本质:
从一个文件中,用输入流对象读取一个字节,再使用输出流,把这字节输出到另一文件中
文件拷贝效率提升:使用一个字节拷贝IO次数比较多,有多少字节,就要io两倍的次数
提升的思路:一次读取多个字节,一次写出多个字节,read(byte[] b) write(byte[] b),减少io次数,提高效率
package Inp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Inpu {
public static void main(String[] args) throws IOException {
med1();
med2();
}
private static void med2() throws IOException {
long t1 = System.currentTimeMillis();
File file = new File("1.mp4");
File file2 = new File("2.mp4");
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file2);
int len = 0;
while ((len = fis.read())!=-1) {
fos.write(len);
}
fos.close();
fis.close();
long t2 = System.currentTimeMillis();
System.out.println("单个字节拷贝效率为"+(t2-t1));
}
private static void med1() throws FileNotFoundException, IOException {
long t1 = System.currentTimeMillis();
File file = new File("1.mp4");
File file2 = new File("22.mp4");
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file2);
int len = 0;
byte[] i = new byte[1024];
while ((len = fis.read(i))!=-1) {
fos.write(i);
}
fos.close();
fis.close();
long t2 = System.currentTimeMillis();
System.out.println("多字节拷贝效率为"+(t2-t1));
}
}
read()和read(byte[] b)方法的比较
读取字节个数的区别:
-
read() 一次读取一个字节
-
read(byte[] b) 一次读取多少,取决于b的大小
读取的内容存储位置不同
-
read() 读取到的内容存储在返回值中
-
read(byte[] b) 读取到的信息存储在数组中
3、返回值得含义不同:
-
read:返回的是读取的内容
-
read(byte[] b):返回的向数组存储数据的长度
-
如果读到-1,说明文件末尾
高效缓冲流
BufferedInputStream 和 BufferedOutputStream
缓冲区的意思
这两个流对象,本身不具备读写的能力,但能提高文件的读取写入效率
构造方法:
-
BufferedInputStream(InputStream is):增强输入流
-
BufferedOutputStream(OutputStream os) :增强输出流
增强的原理:
-
BufferedInputStream:准备个数组,每调用一次read(),增强流就会一次性从文件中读取8192个字节,存到缓冲区中,只会给你返回一个,当再次调用时,就从缓冲区里拿出来一个给你,不会再进行io了,由于数据在内存中获取数据是非常快的,当8192个字节全部读取完,再调用read()方法,他就会再次获取8192个字节,并返回一个,就减少了io的次数提高效率
-
BuffOutputStream:准备个数组,存储输出的信息,当调用write写出一个字节时,不是写到磁盘中,而是先写在缓冲数组中,当大小达到8192时,如果这个数据写满了,就一次性存储到磁盘中,再一次写出,就再准备一个数组,重复操作,写够8192个字节,才会操作一次磁盘
package Inp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Inpu {
public static void main(String[] args) throws IOException {
med3();
med4();
}
private static void med4() throws IOException {
long t1 = System.currentTimeMillis();
File file = new File("1.mp4");
File file2 = new File("bu22.mp4");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(file2);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int len = 0;
byte[] i = new byte[1024];
while ((len = bis.read(i))!=-1) {
bos.write(i);
}
bos.close();
fos.close();
bis.close();
fis.close();
long t2 = System.currentTimeMillis();
System.out.println("多字节拷贝buffer效率为"+(t2-t1));
}
private static void med3() throws IOException {
long t1 = System.currentTimeMillis();
File file = new File("1.mp4");
File file2 = new File("bu2.mp4");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(file2);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int len = 0;
while ((len = bis.read())!=-1) {
bos.write(len);
}
bos.close();
fos.close();
bis.close();
fis.close();
long t2 = System.currentTimeMillis();
System.out.println("单个字节拷贝buffer效率为"+(t2-t1));
}
}
输出流的close()和flush的区别
close()方法被调用前,会自动flush
close()关闭流对象,一旦关了,流对象就不能再用了
flush方法调用后,仅是把文件刷新到缓冲区,并不是把流关了,即调用完后还可以接着调用流
字符流
字节流处理字符问题
- 需要先把字符变为字节数组,才能写到目标文件中
字节读取字符
-
纯英文,每次读取一个字节
-
纯中文,每次读取两个字节(GBK) UTF-8一次读取3个
-
中英文混杂,每次不知道要读取多少字节
字符流的体系
抽象顶层父类:Reader和Writer
字符流具体子类:FileReader和FileWriter
Reader的常用方法
-
close
-
read()
-
read(char[] arr):一次读取一组字符放到arr中,返回值表示放到数组中的字符个数
Writer的常用方法
-
close
-
flush
-
字符流拷贝效率提升write(int c):写出一个字符
-
write(String str): 写出一个字符串
-
write(char[] arr):
-
write(char[] arr,int offset,int len):
都是抽象类,不能实例化,需要使用子类对象来调用方法
字符流的拷贝使用场景:
-
如果在读取字符之后,需要人为阅读,或修改之类,就有必要使用字符流了
-
如果只单纯的文件拷贝,就不需要使用
字符流不能操作流媒体文件:当字符流读取到字节信息,先查询编码表,将其转为字符信息,如果是非纯文本文件了,就有可能读取的字节信息无法转为对应的字符,因为字节信息在编码表中查不到,就会使用?来替代,再输出时,就能查到?的编码,则导致了字节信息被篡改,导致文件不可用
字符流拷贝效率提升同字节流,使用FileReader的read(char[] arr)一次读取一个小数组的字符,能减少io的次数,提高读取效率
FileWriter write(char[] arr) 一次写出一个小数组,同理增加效率
字符的高效缓冲流
和字节同理,只不过数组换成了char
-
BufferedReader:
-
BufferedWriter:
高效缓冲流特有的方法
BufferedReader
- readLine(): 可以从流中,一次读取一行文本,返回一个String对象,读取到末尾的时候返回null
BufferWriter
- newLine(): 写出一个换行符
package Inp;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Fi {
public static void main(String[] args) throws IOException {
med1();
med2();
}
private static void med2() throws IOException {
File file = new File("233.txt");
FileReader fr = new FileReader(file);
int len =0;
while ((len=fr.read())!=-1) {
System.out.println((char)len);
}
fr.close();
}
private static void med1() throws FileNotFoundException, IOException {
File file = new File("233.txt");
File file2 = new File("234.txt");
FileReader fr = new FileReader(file);
FileWriter fw = new FileWriter(file2);
int len =0;
while ((len=fr.read())!=-1) {
fw.write(len);
}
fr.close();
fw.close();
}
}