Java SE IO流
Java SE IO流
目录
file类能够操作文件外部得到内容,无法操作文件内容的内容数据,如果想要操作文件内部的内容通过IO流
1 、IO流
-
IO 流: (文件内容的读入写出,文件的拷贝,文件夹的拷贝,上传与下载…)
-
流: 就是管道
用来传输数据
数据是以先入先出的形式流动传输 -
数据源: 数据的源头
-
目的地: 数据的传输位置
-
中心: 人(大脑),程序为中心
1.1、流的分类:
-
流向分:
输入流
输出流
-
操作单元:
字节流 : 万能流
字符流 : 只能操作纯文本内容 -
功能分:
节点流 : 真是能够做读入写出的流
功能流 : 增强流 -
流的分类都是相辅相成的!!!
1.2、节点流
-
字节输入流 : InputStream 抽象父类,所有字节输入流的父类
字符输入流 :Reader 抽象父类,所有字符输入流的父类 read() 读入… close()关闭
-
字节输出流: OutputStream 抽象父类, 所有字节输出流的父类
字符输出流:Writer 抽象父类,所有字符输出流的父类 writer() 写出 。。。flush() 刷出
2、 InputStream 输入流 字节流
- InputStream 抽象父类,所有字节输入流的父类
- FileInputStream 从文件系统中的文件获取输入字节。 流向: 输入 操作单元:字节流 功能:节点流
File f=new File("D:\\game/feiq/Recv Files/练习题.txt");
//构建流
FileInputStream fio=new FileInputStream(f);
//读入
int[] str=new int[1024];
int num=0;
int i=0;
while ((num=fio.read())!=-1){
str[i]=num;
i++;
System.out.println(str[i]);
}
//关闭
fio.close();
//FileInputStream(File file)
//FileInputStream(String name)
File src = new File("D:\\AAA\\test.txt");
//1.构建流
InputStream is = new FileInputStream(src); //不用子类FileInputStream类型独有内容时候
//2.读入 read() 每次读取一个字节
int num = -1;
while((num = is.read())!=-1){
System.out.println((char)num);
}
//3.关闭
is.close();
//1.创建流
InputStream is = new FileInputStream("D://AAA/test.txt");
//2.读入
//卡车 1024整数倍 一般不超过60倍
byte[] arr = new byte[2];
//len就是读入到数组卡车arr中数据的个数
int len = is.read(arr);
System.out.println(new String(arr,0,len));
//3.关闭
is.close();
3、OutputStream 输出流 字节流
-
OutputStream 所有字节输出流的抽象父类
-
FileOutputStream 文件字节输出流 流向:输出 操作单元: 字节流 工能: 节点流
- write(int) 一次写出一个字节数据 write(byte[]).写出字节数组中所有的数据
- write(byte[],int offset,int length) 写出字节数组中指定的字节是数据…
- flush() 刷出
- close() 关闭
注意:
输出默认覆盖源文件中的内容,可以实现追加
通过字节流实现文件拷贝:
通过程序做中转站
数据源文件–>字节输入流–>程序–>字节输出流–>目的地文件
/* 1.构建流 输出,输出
2.先读入,然后写出
3.输出流刷出
4.关闭流
后打开的先关闭
实现一个图片的拷贝 */
//1.创建流
InputStream is = new FileInputStream("D://AAA/test.txt");
//2.读入
//卡车 1024整数倍 一般不超过60倍
byte[] arr = new byte[2];
//len就是读入到数组卡车arr中数据的个数
int len = -1;
//先把数据读入到卡车中,然后判断读入到的数据个数是否!=-1->-1就为文件末尾没有读到
while((len=is.read(arr))!=-1){
System.out.println(new String(arr,0,len));
}
//3.关闭
is.close();
4、Reader ,Writer字符流
-
输入流 Reader 用于读取字符流的抽象类。
FileReader 文件字符输入流 -
输出流 Writer
FileWriter 文件字符输出流
注意:
- 字符流只能操作纯文本
- 字节流最重要,因为是万能流
//1.流
Reader rd = new FileReader("D://test.txt");
//Writer wd = new FileWriter("D://hahatest.txt");
Writer wd = new FileWriter("D://hahatest.txt",true);//不覆盖原先内容,追加内容
//2.读入写出
//小卡车 char[]
char[] car = new char[1024];
//存储读入到数组中数据的个数
int len = -1;
//重复读
while((len = rd.read(car))!=-1){
wd.write(car,0,len);
wd.write("\r\n"); //换行
}
//3.刷出
wd.flush();
//4.关闭
wd.close();
rd.close();
5、缓冲处理类: Buffered。。。
-
缓冲流 是功能流中的一种
-
增强节点流的读写效率,提高性能
-
InputStream–> BufferedInputStream 字节输入流缓冲流
OutputStream --> BufferedOutputStream 字节输出流缓冲流
无新增方法 -
Reader --> BufferedReader 字符输入缓冲流
String readLine() 读一行文字。 -
Writer --> BufferedWriter 字符输出流的缓冲流
void newLine() 写一个行分隔符。
有新增方法
5.1 、BufferedInputStream 与BufferedOutputStream
5.1.1 构造器
-
BufferedInputStream(InputStream in) 创建一个 BufferedInputStream 并保存其参数,输入流 in ,供以后使用。
-
功能流(节点流)
-
BufferedInputStream(InputStream in, int size) 创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。
-
BufferedOutputStream(OutputStream out) 创建一个 BufferedOutputStream 并保存其参数,输出流 in ,供以后使用。
InputStream io=new BufferedInputStream(new FileInputStream("D:\\haha/d.txt"));
OutputStream os=new BufferedOutputStream(new FileOutputStream("D:\\hehe/w.txt"));
5.1.2 常用方法
- void close() 关闭此输入流并释放与流相关联的任何系统资源。
- int read() 读入字节。
- int read(byte[] b, int off, int len) 从给定的偏移开始,将字节输入流中的字节读入指定的字节数组。
InputStream io=new BufferedInputStream(new FileInputStream("D:\\haha/d.txt"));
OutputStream os=new BufferedOutputStream(new FileOutputStream("D:\\hehe/w.txt"));
byte[] arr=new byte[1024];
int len=-1;
//读入没有值就返回-1
while((len= io.read(arr))!= -1){
//写入
os.write(arr,0,len);
}
//刷
os.flush();
//关闭
os.close();
io.close();
5.2. BufferedReader 与BufferedWiter
5.2.1构造器
- BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。
- BufferedReader(Reader in, int sz) 创建使用指定大小的输入缓冲区的缓冲字符输入流。
- BufferedWriter(Writer wi) 创建缓冲字符输出流。
BufferedReader br=new BufferedReader(new FileReader("D:\\haha/d.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\hehe/w.txt"));
5.2.2 常用方法
- Readr—> String readLine() 读一行文字
- Writer—>void newLine() 写一个行分隔符。
BufferedReader br=new BufferedReader(new FileReader("D:\\haha/d.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\hehe/w.txt"));
String str=null;
//一行读入
while ((str= br.readLine())!=null){
bw.write(str);
bw.newLine();//换行
}
bw.flush();
bw.close();
br.close();
6、转化功能流 字符流
- 处理的都是字符(字节、字符)
- 字符流: 方便,可能不出乱码,但是一旦别人有乱码,你这个流就一定乱码
- 字节流:麻烦,但是只要你能够有机会不乱码,我都可以做到
- 转换流:将字节流转为字符流 处理乱码(编码集、解码集)
字符流:
- InputStreamReader InputStreamReader是从字节流到字符流的桥接器:
- OutputStreamWriter
作用:
- 1.乱码问题。设置编码格式
- 2.流的转换
6.1、构造器
- InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader。
- InputStreamReader(InputStream in, String charsetName) 创建一个使用指定charset的InputStreamReader。
- OutputStreamWriter(OutputStream out) 创建一个使用默认字符集的OutputStreamWriter。
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("D:\\haha/d.txt"),"utf-8"));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\hehe/w.txt",true),"utf-8"));
6.2 常用方法
父类Reader与Writer方法
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("D:\\haha/d.txt"),"utf-8"));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\hehe/w.txt",true),"utf-8"));
String str=null;
while((str=br.readLine())!=null){
bw.write(str);
bw.newLine();
}
bw.flush();
bw.close();
br.close();
7、数据处理流 Data流
-
基本数据类型 + String
-
是字节流功能流的一种
-
功能: 能够是节点流具有传输基本数据类型+数据的能力
-
DataInputStream 基本数据类型输入流
-
DataOutputStream 基本数据类型输出流
新增方法: writeXxx()
注意: 有新增方法不能多态
EOFException 无法正常读取成功(不是源文件)
必须先写,再读。读的顺序必须和写的顺序保持一致
public static void main(String[] args) throws IOException {
test01("D:\\hehe/h.txt");
test02("D:\\hehe/h.txt");
}
public static void test01(String desc) throws IOException {
//1、创建流
DataOutputStream dop=new DataOutputStream(new BufferedOutputStream(new FileOutputStream (desc)));
//2.写出内容
dop.writeInt(123);
dop.writeByte(127);
dop.writeBoolean(false);
dop.writeUTF("fsdsgdg");
byte [] b=new byte[]{1,2,3,4,5};
dop.write(b,0,b.length);
//刷出与关闭
dop.flush();
dop.close();
}
public static void test02(String str) throws IOException {
//创建流
DataInputStream dip=new DataInputStream(new BufferedInputStream(new FileInputStream(str)));
//写出
int i=dip.readInt();
byte b=dip.readByte();
boolean bl=dip.readBoolean();
String s=dip.readUTF();
byte [] b2=dip.readAllBytes();
//打印
System.out.println(i+" "+b+" "+bl+" "+s+ " "+ Arrays.toString(b2));
//关闭
dip.close();
}
8、对象流|Object流 :
所有类型+对象类型
8.0 序列化
- 序列化:是一个用于将对象状态转换为字节流的过程,可以将其保存到磁盘文件中或通过网络发送到任何其他程序
- 反序列化:从字节流创建对象的相反的过程称为 反序列化
8.1、构造器
-
ObjectInputStream 对象字节输入流 | 反序列化输入流
新增方法 Object readObject() 从ObjectInputStream中读取一个对象。 -
ObjectOutputStream 对象字节输出流 | 序列化输出流
新增方法 void writeObject(Object obj) 将指定的对象写入ObjectOutputStream。
注意:
- 读写顺序要保持一致
- 不是所有的类型的对象都能够序列化 实现java.io.Serializable空接口
- 不是所有的属性都需要序列化 transient关键字修饰的字段不会被序列化
- static修饰的成员不会被序列化
- 父类实现了序列化接口,子类所有的内容都能序列化
- 子类实现了序列化接口,子类只能序列化自己的内容,不能序列化父类中继承的内容
*** : 控制版本的更新
- 如果之前的数据的***与当前类型的***id不一致,证明版本不不统一,如果想做版本兼容,需要手动提供一个***id,保证一直不变,就可以实现兼容
- 要求: 类必须实现Serializable空接口
- 子类继承接口只能序列化子类 的。
ObjectInputStream oip=new ObjectInputStream(new FileInputStream(s));
ObjectOutputStream oop=new ObjectOutputStream(new FileOutputStream(s));
8.2 练习
//序列化
public static void writeObj(String s) throws IOException {
//构建流
ObjectOutputStream oop=new ObjectOutputStream(new FileOutputStream(s));
//写出数据
Student s1 = new Student(111111,"zhangsan","hahah","beida",20);
//序列化
oop.writeObject(s1);
String [] s2=new String[]{"fnhjkgnej","rgehfhj","gdhherfhsjfh","Rgrsuiihfuwssf","哈哈UI和符合","All things are empty, all things are allowed"};
oop.writeObject(s2);
//刷出,关闭
oop.flush();
oop.close();
}
//反序列化
public static void readObj(String s) throws IOException, ClassNotFoundException {
//构建流
ObjectInputStream oip=new ObjectInputStream(new FileInputStream(s));
//写入,需要强转
Student sd=(Student) oip.readObject();
String[] st=(String[]) oip.readObject();
System.out.println(sd.toString());
System.out.println(Arrays.toString(st));
//关闭
oip.close();
}
public static void Demo(String desc) throws Exception {
Student s = new Student(111111,"zhangsan","hahah","beida",20);
ObjectOutputStream obos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(desc)));
obos.writeObject(s);
obos.flush();
ObjectInputStream obis = new ObjectInputStream(new BufferedInputStream(new FileInputStream(desc)));
Student s2 = (Student) obis.readObject();
System.out.println(s2.toString());
obos.close();
obis.close();
}
9、Commons-io
commonsio 就是别人写好的一些工具类,我们就是用而已。
CommonsIO 是apache的一个开源的工具包,封装了IO操作的相关类,使用Commons IO可以很方便的读写
文件,url源代码等。
-
commons-IO:
1.下载 jar包
2.把java集成到项目中
3.使用 -
了解: 字节数组流ByteArrayInputStream --> 节点流 一端是程序,另一个端是字节数组
文件流FileInputStream 一段是程序,另一端是文件 -->节点流
9.1、常见类与方法:
- IOUtils 包含一些工具,用于处理读,写和拷贝,这些方法基于 InputStream , OutputStream , Reader 和 Writer 工作。
- FileUtils 包含一些工具,它们基于 File 对象工作,包括读,写,拷贝和比较文件。
//文件的拷贝
//IOUtils.copy(InputStream input, OutputStream output) 自定义使用什么流
//FileUtils.copyFile(File srcFile, File destFile) // 复制文件
FileUtils.copyFile(new File("D:/test.txt"),new File("D:/c.txt"));
IOUtils.copy(new FileInputStream("D:/test.txt"), new FileOutputStream("D:/d.txt"));
//FilenameUtils.getExtension(String filename)
System.out.println(FilenameUtils.getExtension("D://haha123.txt.java"));
//FileUtils.copyDirectory(File srcDir, File destDir) // 复制文件夹(文件夹里面的文件内容/也会复制) 注意:目的地需要完整路径
//FileUtils.copyDirectory(new File("D://AAA"),new File("D://HEHE/AAA"));
//FileUtils.copyDirectory(File srcDir, File destDir, FileFilter filter) // 复制文件夹,
//带有文件过滤功能 了解
FileUtils.copyDirectory(new File("D://AAA"),new File("D://HEHE/AAA"), FileFilterUtils.fileFileFilter());
上一篇: Java SE 8 的Date和Time
下一篇: 2020前端面试笔试题及答案