读写文件: 读进来,写出去
一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。
下图是一个描述输入流和输出流的类层次图
IO流分为字节流和字符流
字节流:以字节为单位进行输入输出,
字符流:以字符为单位进行输入输出
字节流与字符流的读写上基本相同,不同点在于创建流对象上
一. 字节流的两个抽象基类:InputStream,OutputStream
以字节为单位
1. 两个重要的文件字节流是 FileInputStream 和 FileOutputStream:
FileOutputStream: 该类用来创建一个文件并向文件中写数据
方法
-
-
void
close()
关闭此文件输出流并释放与此流相关联的任何系统资源。
protected void
finalize()
清理与文件的连接,并确保当没有更多的引用此流时,将调用此文件输出流的
close
方法。FileChannel
getChannel()
返回与此文件输出流相关联的唯一的
FileChannel
对象。FileDescriptor
getFD()
返回与此流相关联的文件描述符。
void
write(byte[] b)
将
b.length
个字节从指定的字节数组写入此文件输出流。void
write(byte[] b, int off, int len)
将
len
字节从位于偏移量off
的指定字节数组写入此文件输出流。void
write(int b)
将指定的字节写入此文件输出流。
-
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
//如果file文件不存在,则自动创建该文件,每次从文件开头写入数据
FileOutputStream fos = new FileOutputStream(file);
//每次从文件末尾写入数据
//FileOutputStream fos = new FileOutputStream(file,true);
//写入字节流数据
fos.write(97); //写单个字节 a
fos.write("hello! abc.".getBytes()); //getByte()将字符串转换成字节数组
fos.flush();
fos.close();
FileInputStream:该流用于从文件读取数据
方法:
-
-
int
available()
返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
void
close()
关闭此文件输入流并释放与流相关联的任何系统资源。
protected void
finalize()
确保当这个文件输入流的
close
方法没有更多的引用时被调用。FileChannel
getChannel()
返回与此文件输入流相关联的唯一的
FileChannel
对象。FileDescriptor
getFD()
返回表示与此
FileInputStream
正在使用的文件系统中实际文件的连接的FileDescriptor
对象。int
read()
从该输入流读取一个字节的数据。
int
read(byte[] b)
从该输入流读取最多
b.length
个字节的数据为字节数组。int
read(byte[] b, int off, int len)
从该输入流读取最多
len
字节的数据为字节数组。 已经到达文件结尾时返回-1
long
skip(long n)
跳过并从输入流中丢弃
n
字节的数据。
-
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
FileInputStream fis = new FileInputStream(file);
//创建一个字节数组存放读取的字节数据
byte[] buf = new byte[10]; //一次最多读取10个字节
int len = -1;
while((len=fis.read(buf)) != -1) {
String str = new String(buf,0,len);//字节数据构造新的 String
System.out.println(str);
}
fis.close();
//结果
ahello! ab
c.
2. 字节缓冲流(包装流):BufferedInputStream,BufferedOutputStream
作用:为了提高读写效率,不必为写入的每个字节导致底层系统的调用,
减少对磁盘的频繁的读写操作,起到保护磁盘的作用
操作方法和上面的差不多, 具体查看官方 API .
BufferedOutputStream:
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
//写入字节流数据
bos.write(97); //写单个字节 a
bos.write("hello! abc.".getBytes()); //getByte()将字符串转换成字节数组
bos.flush();
bos.close();
BufferedInputStream:
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
//创建一个字节数组存放读取的字节数据
byte[] buf = new byte[10]; //一次最多读取10个字节
int len = -1;
while((len=bis.read(buf)) != -1) {
String str = new String(buf,0,len);//字节数据构造新的 String
System.out.println(str);
}
bis.close();
其他的字节流操作类同上面的操作。
二. 字符流有两个抽象基类:Reader,Writer
以字符为单位
1. 文件字符流:FileReader,FileWriter
FileWriter:
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
FileWriter fw = new FileWriter(file);
//写入字符流数据
fw.write(97); //写单个字符 a
fw.write("hello! abc."); //写字符串
fw.flush();
fw.close();
FileReader:
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
FileReader fr = new FileReader(file);
//创建一个字符数组存放读取的字符数据
char[] cbuf = new char[10];
int len = -1;
while((len=fr.read(cbuf)) != -1) {
String str = new String(cbuf,0,len);//字节数据构造新的 String
System.out.println(str);
}
fr.close();
//结果
ahello! ab
c.
2. 字符流缓冲流:BufferedReader,BufferedWriter
BufferedWriter:
-
-
void
newLine()
写一行行分隔符。
-
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
//写入字符流数据
bw.write(97); //写单个字符 a
bw.newLine(); //写入换行符
bw.write("hello! abc."); //写字符串
bw.flush();
bw.close();
BufferedReader:
-
-
void
close()
关闭流并释放与之相关联的任何系统资源。
Stream<String>
lines()
返回一个
Stream
,其元素是从这个BufferedReader
读取的行。void
mark(int readAheadLimit)
标记流中的当前位置。
boolean
markSupported()
告诉这个流是否支持mark()操作。
int
read()
读一个字符
int
read(char[] cbuf, int off, int len)
将字符读入数组的一部分。
String
readLine()
读一行文字。如果已达到流的末尾,则为null
boolean
ready()
告诉这个流是否准备好被读取。
void
reset()
将流重置为最近的标记。
long
skip(long n)
跳过字符
-
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
//读数据
String str = null;
while((str=br.readLine()) != null) { //readLine()读取一行
System.out.println(str);
}
br.close();
//结果
a
hello! abc.
其他的字符流操作类同上面的操作。
三. 转换流是字符流
作用:字符流和字节流之间沟通的桥梁
OutputStreamWriter : 将字节输出流转换字符输出流
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
//将字节输出流转换字符输出流
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file));
BufferedWriter bw = new BufferedWriter(osw);
//写入字符流数据
bw.write(97); //写单个字符 a
bw.newLine(); //写入换行符
bw.write("hello! abc."); //写字符串
bw.flush();
bw.close();
InputStreamReader : 将字节输入流转换字符输入流
//创建文件
File file = new File("E:/javaSE/file01/text.txt");
//将字节输入流转换字符输入流
InputStreamReader isr = new InputStreamReader(new FileInputStream(file));
BufferedReader br = new BufferedReader(isr);
//读数据
String str = null;
while((str=br.readLine()) != null) { //readLine()读取一行
System.out.println(str);
}
br.close();
//结果
a
hello! abc.
总结:字节流与字符流,操作基本类同,不同点在于创建流对象上 转换流也一样,根据需求转换为文件流 ,缓冲流等。
认真体会读和写的操作过程, 更多查看官方 API .