IO流学习小结
IO流的分类
根据数据流向分为输出流 和输入流
- 输入流:把数据从其他设备读取到内存中的流;
- 输出流:把数据从内存中写出到其他设备的流;
根据数据类型分为字节流和字符流 - 字节流:以字节为单位,读取数据的流;
- 字符流:以字符为单位,读取数据的流;
字节流
一切皆为字节,所有文件数据储存时,都是以二进制数字形式储存的,传输是一样如此。所以字节流可以传输任何文件数据。
字节输出流【OutputStream】
FileOutputStream类:文件输出流,将数据写入到文件中。
写入单个字节:每次写入一个
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 写出数据
fos.write(97); // 写出第1个字节
fos.write(98); // 写出第2个字节
fos.write(99); // 写出第3个字节
// 关闭资源
fos.close();
}
写出字节数组
还可以运用数组一次写入多个数据,运用数组写出指定长度的字节
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("fos.txt");
// 字符串转换为字节数组
byte[] b = "迪迦奥特曼".getBytes();
// 写出字节数组数据
fos.write(b);
// 字符串转换为字节数组
byte[] b = "abcde".getBytes();
// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b,2,2);
// 关闭资源
fos.close();
}
}
数组追加续写
以上程序每次运行,创建输出流对象,都会情况目标文件中的数据
FileOutputStream fos = new FileOutputStream("fos.txt",true);
字节输入流【InputStream】
FileInputStream类: 文件输入流,从文件中读取字节。
读取字节:每次读取一个字节,提升为int类型,读取到文件末尾,返回-1。
// 使用文件名称创建流对象
FileInputStream fis = new FileInputStream("read.txt");
// 读取数据,返回一个字节
int read = fis.read();
System.out.println((char) read);
// 读取到末尾,返回-1
read = fis.read();
System.out.println( read);
// 关闭资源
fis.close();
}
使用while循环改进读取方式,
// 定义变量,保存数据
int b ;
// 循环读取
while ((b = fis.read())!=-1) {
System.out.println((char)b);
}
使用字节数组读取
// 定义变量,作为有效个数
int len ;
// 定义字节数组,作为装字节数据的容器
byte[] b = new byte[2];
// 循环读取
while (( len= fis.read(b))!=-1) {
// 每次读取后,把数组的有效字节部分,变成字符串打印
System.out.println(new String(b,0,len));// len 每次读取的有效字节个数
}
案例实现
// 1.创建流对象
// 1.1 指定数据源
FileInputStream fis = new FileInputStream("D:\\test.jpg");
// 1.2 指定目的地
FileOutputStream fos = new FileOutputStream("test_copy.jpg");
// 2.读写数据
// 2.1 定义数组
byte[] b = new byte[1024];
// 2.2 定义长度
int len;
// 2.3 循环读取
while ((len = fis.read(b))!=-1) {
// 2.4 写出数据
fos.write(b, 0 , len);
}
字符流
使用字节流读取文字时可能会有一些小问题。再遇到中文字符时,可以不会显示完整的字符,因为一个中文字符占用多个字节存储。字符流专门来处理文本文件。
字符输入流【Reader】
FileReader类:构造时使用系统默认的字符编码和默认字节缓冲区。
读取字符
read方法
// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
// 定义变量,保存数据
int b ;
// 循环读取
while ((b = fr.read())!=-1) {
System.out.println((char)b);
}
同理字节输入流,使用字符数组读取
// 定义变量,保存有效字符个数
int len ;
// 定义字符数组,作为装字符数据的容器
char[] c= new char[2];
// 循环读取
while ((len = fr.read(c))!=-1) {
System.out.println(new String(c,0,len));
}
字符输出流【Writer】
FileWriter:把字符写入到文件
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 写出数据
fw.write(97); // 写出第1个字符
写出字符数组
// 字符串转换为字节数组
char[] chars = "迪迦奥特曼".toCharArray();
// 写出字符数组
fw.write(chars); //迪迦奥特曼
// 写出从索引1开始,3个字节。
fw.write(b,1,3); //奥特曼
// 字符串
String msg = "迪迦奥特曼";
// 写出字符数组
fw.write(msg); //迪迦奥特曼
// 写出从索引1开始,3个字节。
fw.write(msg,1,3); //奥特曼
缓冲流【BufferedStream】
缓冲流也叫高效流,是对四个基本Filexxx流的增强,所以也是四个流
缓冲流的基本原理,是在创建流对象时,会创建一个默认的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写效率。
字节缓冲流
// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
// 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
高效测试:
// 创建流对象
try (
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk9.exe"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.exe"));
){
// 读写数据
int len;
byte[] bytes = new byte[8*1024];
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0 , len);
}
} catch (IOException e) {
e.printStackTrace();
}