IO图解及Java中InputStream,OutputStream,FileReader,FileWriter用法
目录
三、InputStream输入流(把数据从文件读取到内存中):
四、OutputStream输出流(把数据从内存写入到目标文件中):
一、IO(输入输出流)图例

输入还是输出是相对内存(缓冲区)而言的,而InputStream和OutputStream读取的是二进制文件
二、字节流和字符流:
| 字节流 | 字符流 | |
| 读取方式 | 基于二进制的读取方式 | 基于字符的读取方式 |
| Java中对应抽象类 | InputStream/OutputStream | Reader/Writer |
| Java中对应实现类 | FileInputStream/FileOutputStream | FileReader/FileWriter |
三、InputStream输入流(把数据从文件读取到内存中):
|
修饰符及
返回值类
型
|
方法名
| 说明 |
|
int
|
read()
|
读取一个字节的数据,返回
-1
代表已经完全读取完成
|
|
int
|
read(byte[]b)
|
最多读取
b.length
字节的数据到
b
中并返回实际读到的数
量;
-1 代表以及读取完成
|
|
int
|
read(byte[] b,
int off, int len)
|
最多读取
len - off
字节的数据到
b
中,放在从
off
开始,返
回实际读到的数量;
-1 代表读取完成
|
| void |
close()
| 关闭字节流(基于二进制的读取方式) |
InputStream代码示例:
import java.io.FileInputStream;
import java.io.IOException;
public class IO_InputStream {
public static void main(String[] args) throws IOException {
//创建输入流读取文件内容
FileInputStream fileInputStream = new FileInputStream("E:\\temp\\test.txt");
System.out.println("=======read()方法=======");
//循环读取
while(true){
//每次只读一个字节
int data = fileInputStream.read();
if( data == -1) break;//读取完毕会返回-1
//返回值为ASCII码值,转换成字符显示
System.out.print((char)data);
}
System.out.println();
System.out.println("=======read(byte[]b)方法=======");
fileInputStream = new FileInputStream("E:\\temp\\test1.txt");
byte[] data = new byte[2];//一次最多读取两个字节长度
while (true){
int len = fileInputStream.read(data);
if(len == -1) break;
for(int i = 0; i < len; i++){
System.out.print((char)data[i]);
}
}
System.out.println();
System.out.println("=======read(byte[] b,int off, int len)方法=======");
fileInputStream = new FileInputStream("E:\\temp\\test2.txt");
data = new byte[4];
int off = 1;//从data[1]开始写入
int length = 2;//每次读取两个字节长度
while (true){
int len = fileInputStream.read(data,off,length);
if(len == -1) break;//读取完成
for(int i = off; i < len+1; i++){
System.out.print((char)data[i]);
}
}
fileInputStream.close();//关闭字节流(关闭水龙头)
}
}
运行结果:

文件内容:

四、OutputStream输出流(把数据从内存写入到目标文件中):
|
修饰符及
返回值类
型
|
方法名
| 说明 |
|
void
|
write(int b)
|
写入要给字节的数据
|
|
void
|
write(byte[] b)
|
将
b
这个字符数组中的数据全部写入
os
中
|
|
int
|
write(byte[] b, int off, int len)
|
将
b
这个字符数组中从
off
开始的数据写入
os
中,一共写
len
个
|
|
void
|
close()
|
关闭字节流
|
|
void
|
flush()
|
重要:我们知道
I/O
的速度是很慢的,所以,大多的 OutputStream 为 了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写
入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的 数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置, 调用
flush
(刷新)操作,将数据刷到设备中。
|
OutputStream代码示例:
import java.io.FileOutputStream;
import java.io.IOException;
public class IO_OutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("E:\\temp\\OutputStream.txt");
//============write(int b)方法============
fileOutputStream.write(97);//字符a
//============write(byte[] b)方法============
byte[] data1 = {98,98,98};//写入三个a
fileOutputStream.write(data1);
//============write(byte[] b, int off, int len)方法============
byte[] data2 = {97, 98, 99, 99, 99, 98, 97};
//写入data2中的三个c即data[2]~data[4]
int off = 2;
int len = 3;
fileOutputStream.write(data2, off, len);
// 刷新一下缓冲区
fileOutputStream.flush();
//关闭字节流
fileOutputStream.close();
System.out.println("完成");
}
}
程序运行前文件内容为空:

程序运行后:


五、FileReader
import java.io.FileReader;
import java.io.IOException;
public class IO_FileReader {
public static void main(String[] args) throws IOException {
// 创建一个读取的字符流
FileReader reader = new FileReader("E:/temp/FileReader.txt");
// 循环读取
while (true) {
int data = reader.read();
// 返回-1表示读取结束
if (data == -1) {
break;
}
// 打印结果
System.out.print((char)data);
}
// 关闭流
reader.close();
}
}
文件内容:

运行结果:

六、FileWriter:
import java.io.FileWriter;
import java.io.IOException;
public class IO_FileWriter {
public static void main(String[] args) throws IOException {
// 创建一个基于字符的输出流
FileWriter writer = new FileWriter("E:/temp/FileWriter.txt");
// 写数据
writer.write("hello world!!!");
writer.write("\n");
writer.write("你好世界!!!");
// 清空缓冲区
writer.flush();
// 关闭流
writer.close();
}
}
运行前文件内容(空文件):

运行后文件内容:

七、注意事项:
①使用flush()刷新的原因(详见上述表格),可以随地调用,但不建议频繁使用,没必要。
②关闭流的原因:进程启动时会在系统中申请资源,包括文件描述符表(就是一个数组)程序打开的每个文件都是一个文件描述符,会被写入到文件描述符表中,每个数据都有大小,如果不关闭字节流,数组始终会被写满,再打开其他文件的时候,数组没有多余空间,程序会卡住,而关闭字节流就是为了把当前文件从文件描述附表中删除。