Java IO原理
- I/O是Input/Output的缩写,I/O技术是用于处理设备之间的数据传输
- 在Java中,数据的传输是通过“流(Stream)”的方式进行
流的分类
- 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
- 按数据流的流向不同分为:输入流,输出流
- 按流的角色的不同分为:节点流,处理流
节点流
- 节点流:直接从数据源或目的地读写数据(文件操作)
处理流
- 处理流:不直接从数据源或目的地读写数据,而是在已有的流上,对数据的处理为程序提供更强大的读写功能(加强读写功能)
流之间的关系图
流的使用
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
对象流 | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter |
打印流 | PrintStream | PrintWriter |
使用流的步骤:
- 创建文件对象
//创建文件对象
File file = new File("rt.txt");
- 创建流
//字节流
FileInputStream fis = new FileInputStream(file);
//字符流
FileReader fr = new FileReader(file);
PS:对文本文件数据操作时使用字符流,对图片、视频、音频等媒体文件数据处理时使用字节流
- 使用流对数据进行读写操作
InputStream
int read()
从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因
为已经到达流末尾而没有可用的字节,则返回值 -1。
int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。如果因为已
经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取
的字节数。
int read(byte[] b, int off,int len)
将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取
的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于
文件末尾而没有可用的字节,则返回值 -1。
public void close() throws IOException
关闭此输入流并释放与该流关联的所有系统资源。
OutputStream
void write(int b)
将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写
入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 即写入0~255范围的。
void write(byte[] b)
将b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该
与调用 write(b, 0, b.length) 的效果完全相同。
void write(byte[] b,int off,int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
public void flush()throws IOException
刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立
即写入它们预期的目标。
public void close() throws IOException
关闭此输出流并释放与该流关联的所有系统资源。
Reader
int read()
读取单个字符。作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff)(2个字节的Unicode码),如果已到达流的末尾,则返回 -1
int read(char[] cbuf)
将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
int read(char[] cbuf,int off,int len)
将字符读入数组的某一部分。存到数组cbuf中,从off处开始存储,最多读len个字
符。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
public void close() throws IOException
关闭此输入流并释放与该流关联的所有系统资源。
Writer
void write(int c)
写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。 即写入0 到 65535 之间的Unicode码。
void write(char[] cbuf)
写入字符数组。
void write(char[] cbuf,int off,int len)
写入字符数组的某一部分。从off开始,写入len个字符
void write(String str)
写入字符串。
void write(String str,int off,int len)
写入字符串的某一部分。
void flush()
刷新该流的缓冲,则立即将它们写入预期目标。
public void close() throws IOException
关闭此输出流并释放与该流关联的所有系统资源。
- 关闭流
流通过调用close()方法即可关闭
FileReader fr = null;
try {
fr = null;
//创建文件
File file = new File("rt.txt");
//创建流
fr = new FileReader(file);
//对数据进行处理
int c;
while ((c = fr.read()) != -1) {
char ch = (char) c;
System.out.print(ch);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
缓冲流
缓冲流的操作只不过就是在流的基础上再进行一次操作,缓冲流提高了数据操作的效率
缓冲流操作的步骤:
- 创建文件对象
- 创建流
- 创建缓冲流
- 使用缓冲流进行数据操作
- 关闭缓冲流(只需关闭缓冲流,缓冲流关闭的同时对应的节点流也会相应关闭)
FileReader fr = null;
BufferedReader br = null;
try {
fr = null;
//创建文件对象
File file = new File("rt.txt");
//创建流
fr = new FileReader(file);
//创建缓冲流
br = new BufferedReader(fr);
//对数据进行处理
int c;
while ((c = br.read()) != -1) {
char ch = (char) c;
System.out.print(ch);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}