文章目录
1、简介
IO流,什么是IO?
I:Input
O:Output
通过IO可以完成对硬盘文件的读和写。
2、IO流的分类
一:按照流的方向进行分类:
以内存作为参照物。往内存中去,叫做输入(Input)。或者叫做读(Read),从内存中出来,叫做输出(Output)。或者叫做写(Write)。
二:按照读取读取数据方式不同进行分类:
有的流是按照字节的方式读取数据,一次读取1个字节byte,等于一次读取8个二进制位,这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件…
有的流是按照字符的方式读取数据这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件也无法读取。
综上所述:流的分类:输入流、输出流、字节流、字符流。
3、IO流四大基类
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
这四个基类都是抽象类。(abstract class)
所有的流都实现了:java.io.Closeable接口,都是可关闭的,即有close() 方法,所以我们在使用流后,记得关闭流,不然会耗费过多的资源。
所有输出流都实现了:java.io.Flushable接口,都是可刷新的,都有flush() 方法,输出流在最终输出之后要记得刷新一下,这表示将通道/管道当中剩余未输出的数据强行输出完,也就是清空管道。
注意:在java中只要"类名"是以stream结尾的都是字节流,以Reader/Writer结尾的都是字符流。
4、需掌握的流
java.io包下需要掌握的流有16个
文件专属流:
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter
转换流:(将字节流转换字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
缓冲流专属:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream
数据流专属
java.io.DataInputStream
java.io.DataOutputStream
标准输出流专属:
java.io.PrintWriter
java.io.PrintStream
对象专属流:
java.io.ObjectInputStream
java.io.ObjectOutputStream
5、FileInutStream
创建test文件
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
//路径写的是绝对路径,我的电脑是Mac book更windows不一样
fis = new FileInputStream("/Users/taofen/IdeaProjects/JavaSE/src/io/test");
#循环读取
while (true){
//开始读
int read = fis.read();
//如果等于-1,代表到达末尾,直接break退出
if (read == -1){
break;
}
System.out.println(read);
#到达末尾在进行读取,返回值为-1
int read1 = fis.read();
System.out.println(read1);
}
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//在finally语句块当中确保流一定关闭
if (fis == null) {
//避免空指针异常
//关闭流的前提是:流不是空。流是null就不需要关闭了
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
上面的代码还是有蛮大问题的,即使用了循环,也还是不好,因为每次只读取一个字节,接下来教给大家读取多个字节的方法
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("/Users/taofen/IdeaProjects/JavaSE/src/io/test");
//采用bytes数组,一次读取多个字节,最多读取 "数组长度"个字节
byte[] bytes = new byte[4];
//这个方法返回值为:读取到的字节数量
int read = fis.read(bytes);
//将字节数组全部转换成字符串
//读取多少个转换多少个,而不是全部读出
System.out.println(new String(bytes,0,read));
int read1 = fis.read(bytes);
System.out.println(new String(bytes,0,read1));
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis == null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileInputStream完美写法
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("/Users/taofen/IdeaProjects/JavaSE/src/io/test");
//采用bytes数组,一次读取多个字节,最多读取 "数组长度"个字节
byte[] bytes = new byte[4];
int readCount = 0;
while ((readCount = fis.read(bytes)) != -1) {
System.out.println(new String(bytes,0,readCount));
}
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis == null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
6、FileInputStream其他方法
available:返回流当中剩余的没有读到的字节数量
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("/Users/taofen/IdeaProjects/JavaSE/src/io/test");
//还没有开始读取,这时使用available读取到的就是总字节数量
System.out.println("总字节数量:"+fis.available());
//读取1个
int read = fis.read();
//查看还可以读取的字节数量
System.out.println(fis.available());
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis == null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
作用:在使用byte数组时可以使用available,这样就不用循环了
缺点:不适合太大的文件
7、FileOutputStream
文件字节输出流,从硬盘到内存
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
#如果没有改文件就创建文件
fos = new FileOutputStream("myfile");
//写
byte[] b = {
97,98,99,100};
fos.write(b);
//写完之后刷新
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
每次新写入是先清空原文件,重新写入
接下来交大家将新内容写入文本末尾处,而不是清空原文件内容
追加成功,原文件没有被清空
写入字符串
8、FileReader
FileReader:文件字符输入流,只能读取普通文本,读取文本内容时,比较方便,快捷。
package io;
import java.io.*;
public class FileReaderTest {
public static void main(String[] args) {
FileReader fr = null;
try {
fr = new FileReader("myfile");
//每次读取4个字符
char[] chars = new char[4];
int readCOunt = 0;
while ((readCOunt = fr.read(chars)) != -1) {
System.out.println(new String(chars,0,readCOunt));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
9、FileWriter
文件字符输出流,写。只能输出普通文本。
package io;
import java.io.*;
public class FileWriterTest {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("file");
char[] chars = {
'我','是','皮','皮','虾'};
fw.write(chars);
fw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
10、带缓冲区的字符流
BufferedReader:带有缓冲区的字符输入流,使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲
package io;
import java.io.*;
public class BufferedReaderTest {
public static void main(String[] args) throws Exception {
FileReader reader = new FileReader("file");
//BufferedReader:包装流,使用BufferedReader把FileReader包装起来
BufferedReader br = new BufferedReader(reader);
//readLine一次读取一行
String s = br.readLine();
System.out.println(s);
//关闭流
br.close();
}
}
对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭,源代码参考如下:
11、转换流
InputStreamReader
package io;
import java.io.*;
public class BufferedReaderTest {
public static void main(String[] args) throws Exception {
//字节流
FileInputStream in = new FileInputStream("file");
//转换流
InputStreamReader reader = new InputStreamReader(in);
//只能传字符流,不能传字节流
BufferedReader br = new BufferedReader(reader);
String str = null;
while ((str = br.readLine()) != null){
System.out.println(str);
}
}
}
合并写法
//合并写法
BufferedReader file = new BufferedReader(new InputStreamReader(new FileInputStream("file")));
String str = null;
while ((str = file.readLine()) != null){
System.out.println(str);
}
执行结果一样的
BufferedWriter
带缓冲区的字符输出流
package io;
import java.io.*;
public class BufferedReaderTest {
public static void main(String[] args) throws Exception {
//带有缓冲区的字符输出流
BufferedWriter ppx = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("ppx")));
//开始写
ppx.write("hello 皮皮虾");
ppx.write("\n");
ppx.write("666");
//刷新
ppx.flush();
//关闭
ppx.close();
}
}
博主会持续更新,有兴趣的小伙伴可以点赞、关注和收藏下哦,你们的支持就是我创作最大的动力!