IO流
File类
java.io.File,使用该类的构造函数就可以创建文件对象,将硬盘中的一个具体的文件以Java对象的形式来表示。
方法 | 描述 |
---|---|
public File(String pathName) | 根据路径创建对象 |
public String getName() | 获取文件名 |
public String getParent() | 获取文件所在目录 |
public File getParentFile() | 获取文件所在目录对应的File对象 |
public String getPath() | 获取文件路径 |
public boolean exists() | 判断文件是否存在 |
public boolean isDirectory() | 判断File对象是否为目录 |
public boolean isFile() | 判断File对象是否为文件 |
public long length() | 获取文件的大小 |
public boolean createNewFile() | 根据当前对象创建新文件(如果不存在就创建) |
public boolean delete() | 删除对象 |
public boolean mkdir() | 根据当前对象创建目录 |
public boolean renameTo(File file) | 为已存在的对象重命名 |
异常如果直接继承自Exception,在实际调用的时候需要手动处理(捕获异常/丢给虚拟机去处理)
方法定义时的异常,如果继承自RuntimException,调用时不需要处理。
File file = new File("F:/java/test2.txt");
try {
System.out.println(file.createNewFile());// 创建新文件
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(file.exists()); // 判断是否存在
file.renameTo(new File("F:/java/test3.txt")); //重命名
file.delete(); //删除
IO流
- 按照方向分,可以分为输入流和输出流
- 按照单位分,可以分为字节流和字符流
- 按照功能分,可以分为节点流和处理流
字节流
按照方向可以分为输入字节流和输出字节流。
InputStream、OutputStream
1 byte = 8 位二进制数
InputStream常用方法
方法 | 描述 |
---|---|
int read() | 以字节为单位,来读取数据(返回当前字节的十进制ASCII码) |
int read(byte b[]) | 将数据存入byte类型的数组中,并返回数组中有效数据的长度 |
int read(byte b[], int off, int len) | 将数据存入byte类型的数组中指定区间内,返回数组中有效数据的长度 |
byte[] readAllBytes() | 将所有数据存入byte数组,并返回数组(JDK1.9) |
int available() | 返回当前数据流中,未读取的数据个数 |
void close() | 关闭数据流 |
//例子1
File file = new File("F:/java/test.txt");
if (file.exists()) {
// 通过流(管道,传输者)读取文件
InputStream inputStream = new FileInputStream(file); // 多态,
long length = file.length();
for (int i = 0; i < length; i++) {
System.out.println(inputStream.read());
}
int temp = 0;
while ((temp = inputStream.read()) != -1){
System.out.println("当前读取到的数据是:"+temp+",当前未读取的"+inputStream.available());
}
}
//例子2
File file = new File("F:/java/test.txt");
if (file.exists()) {
// 1.创建数组
byte[] bytes = new byte[(int)file.length()];
// 2.创建流
InputStream inputStream = new FileInputStream(file);
// 3.读取流
int length = inputStream.read(bytes);
System.out.println(length);
}
// 3
File file = new File("F:/java/test.txt");
if (file.exists()) {
// 1.创建数组
byte[] bytes = new byte[100];
// 2.创建流
InputStream inputStream = new FileInputStream(file);
// 3.读取流
int length = inputStream.read(bytes,10,2);// 2取有效的
System.out.println(length);
}
// 4
File file = new File("F:/java/test.txt");
if (file.exists()) {
InputStream inputStream = new FileInputStream(file);
byte[] bytes = inputStream.readAllBytes();
inputStream.close(); // 关闭
}
OutputStream 常用方法
方法 | 描述 |
---|---|
void write(int b) | 以字节为单位输出(写出)数据,单个 |
void write(byte b[]) | 将byte数组中的数据输出 |
void write(byte b[], int off, int len) | 将byte数组中指定区间的数据输出 |
void close() | 关闭数据流 |
//1
OutputStream outputStream = new FileOutputStream("F:/java/target.txt");
outputStream.write(108);// ASCII码(字节)
outputStream.close();
//2
byte bytes[] = {99,105,108,100,59};
outputStream.write(bytes,3,2);//从数组下标3开始截取长度为2的
字符流
字节流是单位时间内处理一个字节的数据(输入+输出)
字符流是单位时间内处理一个字符的数据(输入+输出)
字符流:
- 输入字符流 Reader
- 输出字符流 Writer
Reader
public abstract class Reader implements Readable, Closeable
是一个抽象类
Readable接口的作用:
可以将数据以字符的形式读入缓冲区
继承关系:**FileReader ** extends InputStramReader extends Reader
节点流:字节流;
处理流:对节点流进行处理,生成其他类型的流
InputStramReader 的功能:处理流,将输入字节流转换为输入字符流
// 1
Reader reader = new FileReader("F:/java/test.txt");
int temp = 0;
System.out.println("___________字符流读取————————————");
while ((temp = reader.read()) != -1) {
System.out.println(temp);
}
InputStream inputStream = new FileInputStream("F:/java/test.txt");
temp = 0;
System.out.println("___________字节流读取————————————");
while ((temp = inputStream.read()) != -1) {
System.out.println(temp);
}
// 2
Reader reader = new FileReader("F:/java/test3.txt");
char[] chars = new char[8];
int length = reader.read(chars);// 将读取出来的数据存到chars数组,返回有效长度
System.out.println("数据流的长度:"+length);
for (char aChar : chars) {
System.out.println(aChar);
}
// 3
int length = reader.read(chars,1,4);// 截取从下标为1开始,长度为4;并放到数组1
read()返回的是int ,直接将字符转换为字节(英1:1,汉1:3),并返回
read(char[] chars) 返回的是char数组,直接就是字符,不会转为字节。
Writer
public abstract class Writer implements Appendable, Closeable, Flushable
Appendable接口:可以将char类型的数据读入到数据缓冲区
继承关系:FileWriter extends OutputStreamWriter extends Writer
OutputStreamWriter 处理流,将输出字节流转换为输出字符流
Writer writer = new FileWriter("F:/java/copy.txt");
// char数组输出到文件
char[] chars = {'你','好','吗'};
writer.write(chars);
//writer.write(chars,1,2);// char数组中,从下标1开始,截取长度为2的到文件
writer.flush();
writer.close();
// 字符串输出到文件
writer.write("您好");
String str = "hellojava,GO";
//writer.write(str,2,3);// 从下标2开始,截取长度为3的到文件
writer.flush();// 字符流有缓冲区,需要清空并同步出来,但是字节流没有缓冲区,不需要;且输入没有缓冲区,没有实现flushable接口,只有输出有,可以flush();
writer.close();
void flush() 将缓冲流中的数据,同步到输出流中,且只有输出有
处理流
// 中间的东西,一般不直接输出
// 基础管道(字节流)
InputStream inputStream = new FileInputStream("F:/java/test.txt");
// 处理流(转换为字符流)
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
char[] chars = new char[1024];
int length = inputStreamReader.read(chars);// 读取到char数组,返回有效长度
inputStreamReader.close();
String result = new String(chars,0,length);
System.out.println(result);
//输出
String str = "你好xiao";
OutputStream outputStream = new FileOutputStream("F:/java/copy.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
outputStreamWriter.write(str,1,2);
outputStreamWriter.flush();
outputStreamWriter.close();
Data:4个
Object:4个
Filter:4个
print:printWriter、printStream
节点流:CharArrayReader。。。(4个)StringReader、Writer
缓冲流
无论是字节流还是字符流,使用的时候都会频繁的访问硬盘,对硬盘是一种损失,同时效率不高,
缓冲流自带缓冲区,可以一次性从硬盘中读取部分数据存入缓冲区,再写入内存,可以有效减少对硬盘的直接访问。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gUPaQKIA-1616079603259)(F:\Desktop\整理\image-20210223163216312.png)]
缓冲流属于处理流
节点流和处理流的区别
1.节点流:可以直接对接到文件对象File
2.处理流:不可以直接对接到文件对象File,必须建立在节点流的基础上才能创建,处理节点流
缓冲流又可以分为,字节缓冲流和字符缓冲流,还可以按输入、输出细分。
字符输入缓冲流 BufferedReader
//字节流 没必要去用 缓冲流 字节输入缓冲流:BufferedInputStream
// 1 readLine()
// 1.创建字符流(节点流)
Reader reader = new FileReader("F:/java/test.txt");
// 2.创建缓冲流(处理流)
BufferedReader bufferedReader = new BufferedReader(reader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {// readLine()读取一行,回车后为一行
System.out.println(str);
}
bufferedReader.close();
reader.close();
// 2 read()
Reader reader = new FileReader("D:/test/test.txt");
BufferedReader bufferedReader = new BufferedReader(reader);
char[] chars = new char[1024];
int length = bufferedReader.read(chars);
System.out.println(length);
for (char aChar : chars) {
System.out.println(aChar);
}
bufferedReader.close();
reader.close();
字节输出缓冲流 BufferedOutputStream(不常用)
// 字节流
OutputStream outputStream = new FileOutputStream("D:/test/test.txt");
// 缓冲流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
String str = "我当时咖啡碱撒发射点来思考附加赛";
byte[] bytes = str.getBytes();
// for (byte aByte : bytes) {
// bufferedOutputStream.write(aByte);
// }
// bufferedOutputStream.write(bytes);
bufferedOutputStream.write(bytes,3,9);// 注意截取是字节
bufferedOutputStream.flush();
bufferedOutputStream.close();
outputStream.close();
字符输出缓冲流 BufferedWriter
// 字符流
Writer writer = new FileWriter("D:/test/test.txt");
// 缓冲流
BufferedWriter bufferedWriter = new BufferedWriter(writer);
String str = "我当时咖啡碱撒发射点来思考附加赛发生发旺旺";
// bufferedWriter.write(str);
bufferedWriter.write(str,4,3);// 注意截取的是字符
// char[] chars = {'J','a','v','a'};
// bufferedWriter.write(chars); //数组
// bufferedWriter.write(22909); // 将ASCII码传入,自动转换为字符(汉字、英文等)
bufferedWriter.flush();
bufferedWriter.close();
writer.close();
输入流没有flush方法,不代表没有缓冲流
输出流是有flush方法,实际开发中,在关闭输出缓冲流之前,需要调用flush方法。
序列化和反序列化
序列化:将内存中的对象输出到硬盘文件中保存
反序列化:相反的操作,从文件中读取数据并还原成内存中的对象。
序列化
1.实体类需要实现序列化接口,Serializable (transient关键字 透明的)
// 实体类
public class User implements Serializable {
}
2.实体类对象进行序列化处理,通过数据流写入到文件中,ObjectOutputStream.
User user = new User(1, "tom", 22);
OutputStream outputStream = new FileOutputStream("D:/test/test.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(user); // 将对象写入
objectOutputStream.flush();
objectOutputStream.close();
outputStream.close();
反序列化
InputStream inputStream = new FileInputStream("D:/test/test.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
User user = (User)objectInputStream.readObject();// 将对象读出
System.out.println(user);
objectInputStream.close();
inputStream.close();
IO流的实际应用
IO流就是完成文件传输(上传文件、文件下载)
复制粘贴
// 字节流(效率低,图片音频等只能用字节流)
// 1.通过输入流将文件读入到 java
InputStream inputStream = new FileInputStream("F:/java/al.jpg");
// 2.通过输出流将文件从 java 写到 文件夹
OutputStream outputStream = new FileOutputStream("F:/sse/copy.jpg");
int temp = 0;
while ((temp=inputStream.read()) != -1){
System.out.println(temp);
outputStream.write(temp);
}
outputStream.flush();
outputStream.close();
inputStream.close();
// 字符流(效率较高)
Reader reader = new FileReader("F:/java/test.txt");
Writer writer = new FileWriter("F:/sse/test.txt");
int temp = 0;
int num = 0;
while ((temp = reader.read()) != -1) {
writer.write(temp);
num++;
}
System.out.println("共读取次数"+num);
reader.close();
writer.flush();
writer.close();
// 缓冲流 来复制(效率高)
// 节点流(字符流)
Reader reader = new FileReader("F:/java/test.txt");
// 缓冲流(处理流)
BufferedReader bufferedReader = new BufferedReader(reader);
Writer writer = new FileWriter("F:/sse/test2.txt");
BufferedWriter bufferedWriter = new BufferedWriter(writer);
int num = 0;
String str = "";
while ((str = bufferedReader.readLine()) != null) { //readLine()读取一行
bufferedWriter.write(str);// 写到文件
num++;
}
System.out.println(num);
bufferedWriter.flush(); //有缓冲流时,只flush缓冲流,writer不需要flush了
bufferedWriter.close();
writer.close();
bufferedReader.close();
reader.close();
// 获取当前系统时间
long time = System.currentTimeMillies();
文本类型的数据,可以用字符流去获取(当然也可以用字节)
非文本类的数据(图片、音频、视频)不能用字符去读取(会打散结构),只能用字节去读。