I/O流
在Java中,数据的输入/输出操作以“流”的方式进行
字节流:以字节为单位获取数据(命名以Stream结尾的一般是字节流)
字符流:以字符为单位获取数据(以Reader/Writer结尾的一般是字符流)
节点流:可以直接从数据源或目的地读写数据
处理流:不直接连接到数据源或目的地,是处理流的流,处理流也叫包装流
FilterInputStream和FilterOutputStream是所有包装流的父类
节点流的父类:InputStream和OutputStream
处理流的父类:FilterInputStream extends InputStream、FilterOutputStream extends OutputStream
使用字节流可以读写任意类型的文件
使用字符流只可以读写文本文件(doc不是文本文件)
使用字符流的好处:处理非英文方便
注意:字符流的底层还是字节流
File类
File类用来代表文件或文件夹
作用:
- 获取文件或文件夹的属性(例如文件名、文件大小等)
- 实现对文件或文件夹的创建和删除
注意:File类不能对文件内容进行操作,内容操作要使用io流
常用方法:
public String getName():获取文件或文件夹的名称,不包含上级路径
public String getAbsolutePath():获取文件的绝对路径,与文件是否存在没关系
public long lastModified():获取最后一次被修改的时间
public long length():获取文件的大小(字节数)
public boolean exists():文件或文件夹是否存在
public boolean isFile():是否是一个文件,如果不存在,则始终为false
public boolean isDirectory():是否是一个目录,如果不存在,则始终为false
public boolean delete():删除文件或者一个空文件夹,不能删除非空文件夹
public void deleteOnExit():退出时删除文件或者文件夹,用于删除临时文件,无返回值
FileInputStream和FileOutputStream
文件字节流
FileInputStream和FileOutputStream是字节流、节点流,数据源和目的地是文件
//创建输入流和输出流
InputStream input = new FileInputStream("e:/in.txt");
OutputStream output = new FileOutputStream("e:/out.txt");
//使用输入流和输出流完成文件复制
int n; //定义一个中转站
n = input.read(); //读一个字节,public int read() 方法返回值为int类型
while(n !=-1) { // n=-1 表示读到了文件末尾
out.write(n); //写一个字节
n = input.read(); //再读一个字节
}
//关闭输入流和输出流
input.close();
output.close();
缺点:中转站太小,速度慢,效率低 ;可以将中转站由一个字节变为一个字节数组,减少读写硬盘次数
//创建输入流和输出流
InputStream input = new FileInputStream("e:/in.txt");
OutputStream output = new FileOutputStream("e:/out.txt");
//使用输入流和输出流完成文件复制
byte[] bytes = new byte[1024]; //定义一个中转站
int length = input.read(bytes); //将读取的文件内容放入到字节数组中,返回读取的字节数
while(length != -1) {
out.write(bytes, 0, length); //将字节数组内容写入文件
length = input.read(bytes); //再读内容到一个字节数组
}
//关闭输入流和输出流
input.close();
output.close();
FileReader和FileWriter
文件字符流
FileReader和FileWriter是字符流、节点流,数据源和目的地是文件
//创建输入流和输出流
Reader input = new FileReader("e:/in.txt");
Writer output = new FileWriter("e:/out.txt");
//使用输入流和输出流完成文件复制
int n; //定义一个中转站
n = input.read(); //读一个字符,public int read() 方法返回值为int类型
while(n !=-1) { // n=-1 表示读到了文件末尾
out.write(n); //写一个字符
n = input.read(); //再读一个字符
}
//关闭输入流和输出流
input.close();
output.close();
//创建输入流和输出流
Reader input = new FileReader("e:/in.txt");
Writer output = new FileWriter("e:/out.txt");
//使用输入流和输出流完成文件复制
char[] chars = new char[1024]; //定义一个中转站
int length = input.read(chars); //将读取的文件内容放入到字符数组中,返回读取的字符数
while(length != -1) {
out.write(chars, 0, length); //将字符数组内容写入文件
length = input.read(chars); //再读内容到一个字符数组
}
//关闭输入流和输出流
input.close();
output.close();
BufferedInputStream和BufferedOutputStream
只使用文件字节流的方式的局限是要从硬盘中读取数据到中转站,而硬盘读取速度是远远低于内存的,因此如果文件较大,则需要多次将数据从硬盘读取到中转站
使用缓冲流的话会在内存中创建输入缓冲区和输出缓冲区,中转站从输入缓冲区读取数据,即从内存到内存,因此可以提高效率

刷新输出缓冲区
方法一:bufferedOutput.close();底层会关闭流之前主动调用flush()
方法二:主动调用 bufferedOutput.flush();
方法三:缓冲区满了会自动刷新
//创建输入流和输出流
InputStream input = new FileInputStream("e:/in.txt");
OutputStream output = new FileOutputStream("e:/out.txt");
BufferedInputStream bufferedInput = new BufferedInputStream(input);
BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
//使用输入流和输出流完成文件复制
int n; //定义一个中转站
n = bufferedInput.read(); //读一个字节,public int read() 方法返回值为int类型
while(n !=-1) { // n=-1 表示读到了文件末尾
bufferedOutput.write(n); //写一个字节
n = bufferedInput.read(); //再读一个字节
}
//关闭输入流和输出流
bufferedInput.close();
bufferedOutput.close();
BufferedReader和BufferedWriter
readLine()底层原理
底层还是一个一个字符地读取,使用StringBuilder的append方法进行拼接操作,遇到换行符后,将StringBuilder(char [])转换为String并返回
注意:不同操作系统中换行符是不同的
Unix系统中 "\n"
Windows系统中 "\r\n"
Mac系统中 "\r"
//创建输入流和输出流
BufferedReader reader = new BufferedReader(new FileReader("e:/in.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("e:/out.txt"));
//使用输入流和输出流(按行读写)
String line = reader.readLine(); //先读一行
while(line != null) {
writer.write(line); //写一行
writer.newLine(); //换行
line = reader.readLine(); //再读一行
}
//关闭输入流和输出流
reader.close();
writer.close();
ObjectInputStream和ObjectOutputStream
文件流、缓冲流读取文件只能按照字节、字节数组方式读取
数据流(DataInputStream和DataOutputStream)和对象流(ObjectInputStream和DataOutputStream)可以实现对各种基本类型和引用类型数据的读写,并保留其本身的类型
数据量只能操作基本数据类型和字符串,对象流还可以操作对象(数据流和对象流的使用方式差不多)
写入的是二进制数据,需要通过对应的输入流来读取
使用对象流读写引用类型的数据,需要相应类实现Serializable接口
import java.io.*;
public class mytest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
write();
read();
}
public static void read() throws IOException, ClassNotFoundException {
InputStream inputStream = new FileInputStream("e:/out.txt");
BufferedInputStream bis = new BufferedInputStream(inputStream);
ObjectInputStream ois = new ObjectInputStream(bis);
//使用输出流
System.out.println(ois.readBoolean());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
System.out.println(ois.readObject());
System.out.println(ois.readObject());
//关闭输出流
ois.close();
}
public static void write() throws IOException {
//创建一个输出流
OutputStream outputStream = new FileOutputStream("e:/out.txt");
BufferedOutputStream bos = new BufferedOutputStream(outputStream);
ObjectOutputStream oos = new ObjectOutputStream(bos);
//使用输出流
oos.writeBoolean(true);
oos.writeDouble(12.6f);
oos.writeUTF("北京");
oos.writeObject(new User("唐三藏", 18));
oos.writeObject(new User("x", 25));
//关闭输出流
oos.close();
}
}
class User implements Serializable{
String name;
int age;
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
其他流
打印流
PrintStream和PrintWriter
只有输出流,没有输入流
PrintStream 可以将各种类型的数据写入文件,不能保留原来的类型,都编程String类型
转换流
InputStreamReader和OutputStreamWriter
实现字节流到字符流的转换,是适配器模式的应用
只能从字节流转换为字符流,可以带来处理字符的便利;没有字符流转换为字节流的转换流,因为没有这种需求
字节数组流
ByteArrayInputStream和ByteArrayOutputStream是字节流、节点流,数据源和目的地都是一个字节数组
CharArrayReader和CharArrayWriter是字符流、节点流,数据源和目的地是一个字符数组
//创建输入流和输出流InputStream input = new FileInputStream("e:/in.txt");OutputStream output = new FileOutputStream("e:/out.txt");BufferedInputStream bufferedInput = new BufferedInputStream(input);BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);//使用输入流和输出流完成文件复制int n;//定义一个中转站n = bufferedInput.read();//读一个字节,public int read() 方法返回值为int类型while(n !=-1) {// n=-1 表示读到了文件末尾bufferedOutput.write(n);//写一个字节n = bufferedInput.read();//再读一个字节}//关闭输入流和输出流bufferedInput.close();bufferedOutput.close();
浙公网安备 33010602011771号