一:IO流的概述
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
二:IO流的分类
按照数据流向
输入流 读入数据
输出流 写出数据
按照数据类型
字节流 可以读写任何类型的文件 比如音频 视频 文本文件
字符流 只能读写文本文件
三:IO流基类概述
字节流的抽象基类:
InputStream ,OutputStream。
字符流的抽象基类:
Reader , Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
四:IO流中常用的类的功能
字节流
InputStream
(*) FileInputStream 从文件读取字节
(*) BufferedInputStream 加入缓冲功能,提高文件的读取效率
ByteArrayInputStream 从字节数组变成输入流
OutputStream
(*) FileOutputStream 向文件写入字节
(*) BufferedOutputStream 加入缓冲功能, 提高文件的写入效率
ByteArrayOutputStream 把流的内容写入字节数组
PrintStream 实际上就是 System.out
字符流
Reader
(*) InputStreamReader 转换字节流为字符流
(*) BufferedReader 功能增强,以行为单位读取数据 (装饰器模式)
FileReader 是InputStreamReader子类,将字符编码固定为操作系统的默认编码,不能手工改动
Writer
(*) OutputStreamWriter 转换字节流为字符流
(*) PrintWriter 以行为单位写入数据
write 当成字符写入
print print就是将参数转为字符串后写入
FileWriter 是OutputStreamWriter的子类,也是固定了字符编码
举例:
FileInputStream 从文件读取字节.
1)一次读入一个字节
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestFileInputStream1 {
// 测试文件输入流,读取外部文件的内容
public static void main(String[] args) throws IOException {
// 1. 创建输入流对象
FileInputStream fis = new FileInputStream(new File("1.txt"));
// FileInputStream fis = new FileInputStream("1.txt")
// 2. 读取内容
/*int read = fis.read();// 一次读取一个字节, 返回int中只用了一个字节
System.out.println((char)read);
read = fis.read();
System.out.println((char)read);
read = fis.read();
System.out.println((char)read);
read = fis.read();
System.out.println(read);*/
while(true) {
int read = fis.read();
if(read == -1) {
break;
}
System.out.println(read);
}
}
}
2)一次读入多个字节
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
public class TestFileInputStream2 {
public static void main(String[] args) throws IOException {
// 1. 创建输入流对象
FileInputStream fis = new FileInputStream(new File("1.txt"));
// 2. 一次读取多个字节
byte[] buf = new byte[2];
/*int len = fis.read(buf);// 将读到的内容填充到byte数组中,返回的是读到的字节总数, 返回-1还是表示读取完毕了
System.out.println(len);
System.out.println(Arrays.toString(buf));
len = fis.read(buf);
System.out.println(len);
System.out.println(Arrays.toString(buf));
len = fis.read(buf);
System.out.println(len);*/
while(true) {
int n = fis.read(buf);
if(n == -1) {
break;
}
System.out.println(Arrays.toString(buf));
}
}
}
FileOutputStream 向文件写入字节
import java.io.FileOutputStream;
public class TestFileOutputStream {
public static void main(String[] args) throws Exception{
// 1.创建了输出流
FileOutputStream fos = new FileOutputStream("2.txt");
// 2. 向输出流写入内容
// 一次写入一个字节
// fos.write(97);
// fos.write(98);
// fos.write(99);
// 覆盖原有内容 一次写入多个字节
// fos.write(new byte[]{100,100,100,101});
// 一次写入多个字节, 写入数组的一部分, off 代表下班, len 代表长度
fos.write(new byte[]{100,100,100,101,102}, 0, 3 );
// 3. 关闭输出流
fos.close();
}
}
InputStreamReader 转换字节流为字符流
import java.io.*;
import java.util.Arrays;
public class TestInputStreamReader {
public static void main(String[] args) throws IOException {
// 1. 将字节流转换为字符流
FileInputStream fis = new FileInputStream("1.txt");
// 注意:实际文件编码要与读取时的文件编码一致
InputStreamReader reader = new InputStreamReader(fis, "utf-8");
// 2. 读取
/*while(true) {
int c = reader.read();
if(c == - 1) {
break;
}
System.out.println((char)c);
}*/
while(true) {
char[] buf = new char[1024];
int len = reader.read(buf);
if(len == -1) {
break;
}
System.out.println(Arrays.toString(buf));
}
// 3. 关闭, 只需要关闭外层的流, 内部会帮我们关掉内层的流
reader.close();
}
}
BufferedInputStream 加入缓冲功能,提高文件的读取效率
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestBufferedInputStream {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("E:\\youtube\\Getting Started with Spring Boot-sbPSjI4tt10.mp4");
BufferedInputStream bis = new BufferedInputStream(fis, 1024*1024);
byte[] buf = new byte[1024];
while(true) {
int len = bis.read(buf);
if(len == -1) {
break;
}
}
bis.close();
long end = System.currentTimeMillis();
System.out.println("运行时间"+(end-start));
}
}
BufferedReader 功能增强,以行为单位读取数据 (装饰器模式)
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class TestBufferedReader {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("1.txt");
InputStreamReader reader = new InputStreamReader(fis, "utf-8"); // 被装饰的类
BufferedReader reader2 = new BufferedReader(reader); // 对其他的reader做了增强(装饰)
/*System.out.println(reader2.readLine()); // 以行为单位读取数据
System.out.println(reader2.readLine()); // 以行为单位读取数据
System.out.println(reader2.readLine()); // 以行为单位读取数据*/
while(true) {
String line = reader2.readLine();
if(line == null) {
break;
}
System.out.println(line);
}
reader2.close();
}
}
ByteArrayInputStream 从字节数组变成输入流
ByteArrayOutputStream 把流的内容写入字节数组
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
public class TestByteArray {
public static void main(String[] args) {
ByteArrayInputStream bis = new ByteArrayInputStream(new byte[]{97,98,99});
System.out.println(bis.read());
System.out.println(bis.read());
System.out.println(bis.read());
System.out.println(bis.read());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(97);
bos.write(98);
bos.write(99);
byte[] result = bos.toByteArray(); // 获得最终的字节数组
System.out.println(Arrays.toString(result));
}
}
PrintWriter 以行为单位写入数据
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class TestPrintWriter {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("1.txt");
OutputStreamWriter w2 = new OutputStreamWriter(fos, "utf-8");
PrintWriter writer = new PrintWriter(w2);
// writer.write() 将参数当成字符写入
writer.print(10); // print就是将参数转为字符串后写入
writer.print(10.0);
writer.println("ok");
writer.println("ok2");
writer.close();
}
}
文件拷贝举例:
//第一种方式
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
// 文件的复制例子
public class TestFileCopy {
public static void main(String[] args) {
FileInputStream fis = null; // fis,fos要定义在try块外面,并给null值
FileOutputStream fos = null;
try {
fis = new FileInputStream("1.txt");
fos = new FileOutputStream("3.txt");
while (true) {
byte[] buf = new byte[1024];
int len = fis.read(buf);
if (len == -1) {
break;
}
fos.write(buf, 0, len); // 实际读到len个字节,就写入len个字节
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if(fis!=null) { // 不为null时才能关闭
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos!=null) { // 不为null时才能关闭
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//第二种方式
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class TestFileCopy2 {
public static void main(String[] args) throws IOException {
// 最后的参数是在3.txt已存在的情况下替换
Files.copy(Paths.get("1.txt"), Paths.get("3.txt"), StandardCopyOption.REPLACE_EXISTING);
}
}