JavaIO 输入输出流
⭐File类
在Java的iO包中,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() | 测试此抽象路径名表示的文件是否是一个目录。 |
public boolean isFile() | 测试此抽象路径名表示的文件是否是一个标准文件。 |
public long length() | 返回由此抽象路径名表示的文件的长度。 |
public boolean createNewFile() throws IOException | 当且仅当不存在具有此抽象路径名指定的名称的文件时,原子地创建由此抽象路径名指定的一个新的空文件。 |
public boolean delete() | 删除此抽象路径名表示的文件或目录。 |
public boolean mkdir() | 创建此抽象路径名指定的目录。 |
public boolean renameTo(File dest) | 重新命名此抽象路径名表示的文件。 |
⭐注意:
- 方法定义时的异常如果直接继承自Exception,事迹调用的时候需要手动处理(捕获异常/丢给虚拟机去处理)。
- 方法定义时的异常如果继承自RuntimeException,调用的时候不需要处理。
- 创建File对象必须传绝对路径,不可以是相对路径,File他是读取硬盘里面的东西,跟读取配置文件是两回事,读取配置文件可以使用相对路径。
IO流
⭐按照方向分,可以分为输入流和输出流
⭐按照单位分,可以分为字节流和字符流。
⭐按照功能分,可以分为节点流和处理流。
字节流
字节流有输入字节流和输出字节流
InputStream、OutputStreama
1 byte = 8位二进制数 01010101
⭐InputStream常用方法
方法 | 描述 |
---|---|
int read() | 以字节为单位读取数据 |
int read(byte b[]) | 将数据存入byte类型的数据中,返回数组长度 |
int read(byte b[],int off,int len) | 将数据存入byte数组的指定区间内,返回数组长度 |
byte[] readAllBytes() | 将所有数据存入byte数组并返回 |
int available() | 返回当前数据流未读取的数据个数 |
void close() | 关闭数据流 |
⭐注意:
InputStream是抽象类,不能被实例化,如果要实例化必须使用抽象类的子类,FileInputStream。
要处理一下文件不存在的异常
package com.oyrf.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class TestIO1 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\test.txt");
if (file.exists()){
//创建流
InputStream inputStream = new FileInputStream(file);
int asknum = 0;
while ((asknum = inputStream.read())!=-1){
System.out.println(asknum);
}
//关闭流
inputStream.close();
}
}
}
package com.oyrf.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class TestIO2 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\test.txt");
if (file.exists()){
//创建数组
byte[] info = new byte[10];
//创建流
InputStream inputStream = new FileInputStream(file);
int length = inputStream.read(info);
//读取流
System.out.println(length);
//关闭流
inputStream.close();
}
}
}
注意:此处有一个容易犯的错误,不可以这样写,因为没存到内存中,取出来的数据要存到内存中,错误如下图。
package com.oyrf.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class TestIO2 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\test.txt");
if (file.exists()){
//创建数组
byte[] info = new byte[10];
//创建流
InputStream inputStream = new FileInputStream(file);
//读取流
System.out.println(inputStream.read(info));
//关闭流
inputStream.close();
}
}
}
⭐OutputStream常用方法
方法 | 描述 |
---|---|
void write(int b) | 以字节为单位输出数据 |
void write(byte b[]) | 将byte数组中的数据输出 |
void write(byte b[],int off,int len) | 将byte数组中指定区间的数据输出 |
void close() | 关闭数据流 |
void flush() | 将缓冲流中的数据同步到输出流中 |
⭐注意:输入流的话文件是必须要存在的,但是输出流的话文件可以不存在,会自动帮你创建。
package com.oyrf.io;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class TestIO4 {
public static void main(String[] args) throws Exception{
OutputStream outputStream = new FileOutputStream("E:\\javaIO\\src\\com\\oyrf\\io\\target.txt");
outputStream.write(1234);
outputStream.close();
}
}
⭐注意:这里写入的不是1234,而是1234对应的ASCII编码,因为这里使用的是字节流传输。
package com.oyrf.io;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class TestIO5 {
public static void main(String[] args) throws Exception {
OutputStream outputStream = new FileOutputStream("E:\\javaIO\\src\\com\\oyrf\\io\\target.txt");
byte[] bytes = {100,100,100};
outputStream.write(bytes);
outputStream.close();
}
}
package com.oyrf.io;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class TestIO5 {
public static void main(String[] args) throws Exception {
OutputStream outputStream = new FileOutputStream("E:\\javaIO\\src\\com\\oyrf\\io\\target.txt");
byte[] bytes = {11,22,33,44,55,66,77,88,99,100};
outputStream.write(bytes,3,3);
outputStream.close();
}
}
⭐注意:新数据其实会覆盖掉旧数据。
字节流
字节流是单位时间内处理一个字节的数据(输入+输出)
字符流是单位时间内处理一个字符的数据(输入+输出)
字符流:
- 输入字符流 Reader
- 输出字符流 Writer
Reader
是一个抽象类
- 方向:输入+输出
- 单位:字节+字符
- 功能:节点流(字节流)+处理流(对节点流进行处理,生成其他类型的流)
InputStream(字节输入流) ---->Reader(字符输入流)
InputStreamReader的功能是将字节输入流转换为字符输入流
英⽂、数字、符号
1 个字节 = 1 个字符
a 1 个字符、1 个字节
汉字
1 个字符 = 3 个字节
好 1个字符、3 个字节
package com.oyrf.io;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.Reader;
public class TestIO6 {
public static void main(String[] args) throws Exception{
//字符流
Reader reader = new FileReader("E:\\javaIO\\src\\com\\oyrf\\io\\target.txt");
int info = 0;
System.out.println("***********字符流***********");
while ((info =reader.read())!=-1){
System.out.println(info);
}
//字节流
InputStream inputStream = new FileInputStream("E:\\javaIO\\src\\com\\oyrf\\io\\target.txt");
System.out.println("***********字节流***********");
while ((info = inputStream.read())!=-1){
System.out.println(info);
}
}
}
⭐⭐⭐注意:如果文件中的内容是英文,那是没有区别的,但是如果文件的内容是中文,那就会有区别,原因就是上面所说的。
package com.oyrf.io;
import java.io.FileReader;
import java.io.Reader;
public class TestIO7 {
public static void main(String[] args) throws Exception {
Reader reader = new FileReader("E:\\javaIO\\src\\com\\oyrf\\io\\target.txt");
char infos[] = new char[8];
int length = reader.read(infos);
System.out.println("字符数组的长度是" + length);
System.out.println("便利字符数组");
for (char info : infos) {
System.out.println(info);
}
}
}
⭐这里就和字节无关了,因为他是以字符的形式输出
read() 返回的是 int ,直接将字符转成字节(1-1,1-3)
read(char[] chars) 返回的是 char 数组,直接就返回字符,不会转
成字节的。
处理流
package com.oyrf.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
public class TestIO9 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\copy.txt");
//基础管道
InputStream inputStream = new FileInputStream(file);
//处理流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
char chars[] = new char[20];
int len = inputStreamReader.read(chars);
inputStreamReader.close();
String result = new String(chars,0,len);
System.out.println(chars);
System.out.println(result);
}
}
package com.oyrf.io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class TestIO10 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\copy.txt");
OutputStream outputStream = new FileOutputStream(file);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
char[] chars = {'恭','喜','发','财','万','事','如','意'};
outputStreamWriter.write(chars);
outputStreamWriter.append(chars[0]);
outputStreamWriter.flush();
outputStreamWriter.close();
}
}
缓冲流
⽆论是字节流还是字符流,使⽤的时候都会频繁访问硬盘,对硬盘
是⼀种损伤,同时效率不⾼,如何解决?
可以使⽤缓冲流,缓冲流⾃带缓冲区,可以⼀次性从硬盘中读取部
分数据存⼊缓冲区,再写⼊内存,这样就可以有效减少对硬盘的直
接访问。
缓冲流属于处理流,如何来区分节点流和处理流?
1、节点流使⽤的时候可以直接对接到⽂件对象 File
2、处理流使⽤的时候不可以直接对接到⽂件对象 File,必须要建⽴
在字节流的基础上才能创建。
缓冲流⼜可以分为字节缓冲流和字符缓冲流,按照⽅向再细分,⼜
可以分为字节输⼊缓冲流和字节输出缓冲流,以及字符输⼊缓冲流
和字符输出缓冲流。
⭐字节输入缓冲流
package com.oyrf.io;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class TestIO11 {
public static void main(String[] args) throws Exception {
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\copy.txt");
InputStream inputStream = new FileInputStream(file);
//创建缓冲流
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
/* int temp = 0;
while((temp=bufferedInputStream.read())!=-1){
System.out.println(temp);
}*/
byte[] bytes = new byte[30];
int length = bufferedInputStream.read(bytes);
System.out.println(length);
for (byte abyte :bytes){
System.out.println(abyte);
}
bufferedInputStream.close();
inputStream.close();
}
}
⭐字符输入缓冲流
package com.oyrf.io;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class TestIO12 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\copy.txt");
//1、创建字符流(节点流)
Reader reader = new FileReader(file);
//2、创建缓冲流(处理流
BufferedReader bufferedReader = new BufferedReader(reader);
String str = null;
int num = 0;
System.out.println("start");
while ((str=bufferedReader.readLine())!=null){
System.out.println(str);
num++;
}
System.out.println("一共读了"+num+"次");
bufferedReader.close();
reader.close();
}
}
⭐字节输出缓冲流
package com.oyrf.io;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public class TestIO13 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\copy2.txt");
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
String str = "恭喜发财!!!!!!!!!";
byte[] Strbyte = str.getBytes(StandardCharsets.UTF_8);
bufferedOutputStream.write(Strbyte);
bufferedOutputStream.close();
outputStream.close();
}
}
⭐字符输出缓冲流
package com.oyrf.io;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class TestIO14 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\copy2.txt");
String str = "新年祝词一、喜悦伴着汗水,成功伴着艰辛,遗憾激励奋斗,我们不知不觉地走进了2022年,这是信息中心成立后的第五个年头了,在新年来临之际,首先我代表信息中心祝各位新年快乐,万事如意!\n" +
"新年祝词二、祝您好事连连,好梦圆圆!拜新年\n" +
"贺新春!迎新年!祝你今年中大奖。万事顺!合家欢!愿君如意福满年。拜新年\n" +
"加薪买房购小车,娶妻生子成家室!接财神\n" +
"一片绿叶,饱含着它对根的情谊;一句贺词,浓缩了我对您的祝愿。又是一个美好的开始――新年岁首,祝成功和快乐永远伴随着您。拜新年\n" +
"发财无限,使劲赚钱!接财神\n" +
"新年祝福无限,发财跨越2022!接财神";
Writer writer = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
bufferedWriter.write(str);
bufferedWriter.flush();
bufferedWriter.close();
writer.close();
}
}
序列化和反序列化
序列化就是将内存中的对象输出到硬盘⽂件中保存。
反序列化就是相反的操作,从⽂件中读取数据并还原成内存中的对
象。
⭐序列化
- 实体类需要实现序列化接⼝,Serializable
package com.oyrf.entity;
import java.io.Serializable;
public class User implements Serializable {
String username;
int password;
int age;
public User(String username, int password, int age) {
this.username = username;
this.password = password;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getPassword() {
return password;
}
public void setPassword(int password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password=" + password +
", age=" + age +
'}';
}
}
- 实体类对象进⾏序列化处理,通过数据流写⼊到⽂件中,ObjectOutputStream。
package com.oyrf.io;
import com.oyrf.entity.User;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class TestIO15 {
public static void main(String[] args) throws Exception{
User user = new User("Box",123,22);
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\obj.txt");
OutputStream outputStream = new FileOutputStream(file);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(user);
objectOutputStream.flush();
objectOutputStream.close();
outputStream.close();
}
}
⭐反序列化
package com.oyrf.io;
import com.oyrf.entity.User;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
public class TestIO16 {
public static void main(String[] args) throws Exception{
File file = new File("E:\\javaIO\\src\\com\\oyrf\\io\\obj.txt");
InputStream inputStream = new FileInputStream(file);
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
User user = (User) objectInputStream.readObject();
System.out.println(user);
objectInputStream.close();
inputStream.close();
}
}
IO 流的应⽤
IO 流就是完成⽂件传输(上传⽂件:发朋友圈、换头像,⽂件下
载:优快云 下载源代码、⽂档)
字符 a 你好
⽂本类型的数据(txt、word、Excel、MD)可以使⽤字符去读取
(当然也可以⽤字节)
package com.oyrf.io;
import java.io.*;
public class TestIO17 {
public static void main(String[] args) throws
Exception {
Reader reader = new
FileReader("E:\\javaIO\\src\\com\\oyrf\\io\\test.txt);
BufferedReader bufferedReader = new
BufferedReader(reader);
Writer writer = new
FileWriter("E:\\javaIO\\src\\com\\oyrf\\io\\test2.txt");
BufferedWriter bufferedWriter = new
BufferedWriter(writer);
String str = "";
int num = 0;
while ((str =
bufferedReader.readLine())!=null){
bufferedWriter.write(str);
num++;
}
System.out.println("传输完毕,共读取
了"+num+"次");
bufferedWriter.flush();
bufferedWriter.close();
writer.close();
bufferedReader.close();
reader.close();
}
}
⾮⽂本类型的数据(图⽚、⾳频、视频)不能⽤字符去读取,只能
⽤字节去读。
package com.oyrf.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class Test {
public static void main(String[] args) throws
Exception {
//1、通过输⼊流将⽂件读⼊
InputStream inputStream = new
FileInputStream("E:\\javaIO\\src\\com\\oyrf\\io\\1.jpg");
//2、通过输出流将⽂件写⼊
OutputStream outputStream = new
FileOutputStream("E:\\javaIO\\src\\com\\oyrf\\io\\2.jpg");
int temp = 0;
int num = 0;
long start = System.currentTimeMillis();
while((temp = inputStream.read())!=-1){
num++;
outputStream.write(temp);
}
long end = System.currentTimeMillis();
System.out.println("传输完毕,共耗时"+(end-start));
outputStream.flush();
outputStream.close();
inputStream.close();
}
}