IO流可以分为两大类
字节流
是最基本的流,可以操作所有文件: 父类:InputStream和OutputStream 这两个是接口,需要生成子类对象使用
字节输出流InputStream负责将文件中内容读出,读出的方式一共可分成四种:
一次读取一个字节数组
// 字节输出流一次读出一个字节
InputStream is = new FileInputStream("mm.txt");
int len = 0;
while ((len = is.read()) != -1) {
System.out.print((char)len);
}
一次读取一个字节数组
//字节输出流一次读取一个字节数组
InputStream is = new FileInputStream("mm.txt");
int len = 0;
byte[] by = new byte[1024];
while((len = is.read(by))!=-1) {
System.out.println(new String(by,0,len));
}
自带缓冲区的字节输出流 一次读取一个字节
// 自带缓冲区的字节输出流 一次读取一个字节
// 采用默认缓冲区大小
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("mm.txt"));
int len = 0;
while ((len = bis.read()) != -1) {
System.out.print((char) len);
}
自带缓冲区字节输出流 一次读取一个字节数组
// 自带缓冲区的字节输出流 一次读取一个字节
// 采用默认缓冲区大小
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("mm.txt"));
int len = 0;
byte[] by = new byte[1024];
while ((len = bis.read(by)) != -1) {
System.out.print(new String(by,0,len));
}
字节输入流OutputStream
负责向文件中写数据,与输出流方法对应,也是包括四种方式,一次写入一个字节,一次写入一个字节数组,自带缓冲区的一次写入一个字节,自带缓冲的一次写入一个字节数组 ,代码略。
需要注意的细节
文件从输出流 经过输入流写到另一个文件中时,源文件和目的文件一定要写对
//文件的格式一定要对应正确
//输出流
FileInputStream fis = new FileInputStream("D://image/dong.jpg");
//输入流
FIleOutputStream fos = new FileOutputStream("E://dong.jpg");
一次读取一个字节时,若是显示在控制台上,则中文会显示乱码,其原因是因
为汉字是由多个字节组成的,每读取一个字节,就显示在控制台,就好像是 把汉字拆开了,所以控制台识别不了,但是若是直接输入到文件中则不会发
生这种情况,因为字节输出流会自动将字节组合。
自带缓冲区的输入输出流 传输数据的速度更快,根据需要若传输数据较大 时,调用flush方法刷新一下缓冲区
提问:什么叫缓冲区?
在很多地方都碰到缓冲区这个名词,那么到底什么是缓冲区?又有什么作用呢?
回答:缓冲区可以简单地理解为一段内存区域。
可以简单地把缓冲区理解为一段特殊的内存。
某些情况下,如果一个程序频繁地操作一个资源(如文件或数据库),则性能会很低,此时为了提升性能,就可以将一部分数据暂时读入到内存的一块区域之中,以后直接从此区域中读取数据即可,因为读取内存速度会比较快,这样可以提升程序的性能。
字符流
字符流是字节流的在某方面的优化,可以这样理解,一次传输一个字符比一次传输一个字节速度快的多,所有数据都可以用字节流操作,可以用字符流操作的都是可以用windows记事本打开,且打开后我们能看懂的(低俗的理解)。
字符流的父类是Writer和Reader,类型是抽象类,需要生成子类对象使用
字符流的构造:字节流+编码表 = 字符流
//字节转换字符流,将字节流和编码表包装成字符流
InputStreamReader isr = new InputStreamReader(new FileInputStream("mm.txt"));
OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream("mm.txt"));
也可以直接使用转换流的子类,更加方便
FileReader fr = new FileReader("mm.txt");
FileWriter fw = new FileWriter("mm.txt");
自带缓冲区的字符流 高级方法:一次读取一行或一次写入一行
一次写入一行:
BufferedWriter bw = new BufferedWriter(new FileWriter("mm.txt"));
for (int i = 0; i < 10; i++) {
bw.write("hello" + (i + 1));
bw.newLine();
bw.flush();
}
bw.close();
一次读取一行:
BufferedReader br = new BufferedReader(new FileReader("mm.txt"));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
注意:使用readline()方法时:
- 通过下列字符之一即可认为某行已终止:换行 (‘\n’)、回车 (‘\r’) 或回车后直接跟着换行。
- 包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null 。
其中的输入和输出方法和字节流操作相似,在这里不再赘述。
需要注意的点:
向文件中输入数据时,若输入数据较小,则调用close()方法,就可以将数据全部从输出流中刷出,但如果写入的数据较多,则在适当时候要调用flush()方法刷新一下输出流。