一、File 文件类
封装一个磁盘路径字符串,对这个路径可以执行一次操作。
可以用来封装文件路径、文件夹路径、不存在的路径。
1、创建对象
new File(路径);
File file = new File("E:\\abc\\1.txt");
2、 常用方法
文件、文件夹属性
file.length():文件的字节量、长度
file.exists():是否存在,存在返回 true
file.isFile():是否为文件,是文件返回 true
file.isDirectory():是否为文件夹,是文件夹返回true
file.getName():获取文件/文件夹名
file.getParent():获取上一级目录的路径
file.getAbsolutePath():获取文件的绝对路径
创建、删除.
file.createNewFile():新建文件,文件已经存在返回false
file.mkdirs():新建多层文件夹\a\b\c
file.mkdir():新建单层文件夹\a
file.delete():删除文件,删除空文件夹
文件夹列表.
list):返回String[],包含文件名
listFiles():返回 Filel[],包含文件对象
实战练习
public static void main(String[] args) throws IOException {
//1.创建文件对象
//参数是具体的路径,这个路经可以是文件路径也可以是文件夹路径
File file = new File("G:\\abc\\1.txt");
//2、测试常用方法
// 文件、文件共属性
System.out.println(file.length());//14 文件的字节量
System.out.println(file.exists());//true 是否存在
System.out.println(file.isFile());//true 是否为文件
System.out.println(file.isDirectory());//false 是否为文件夹
System.out.println(file.getName());//1.txt 获取文件/文件夹名
System.out.println(file.getParent());//G:\abc 获取上一级的路径
System.out.println(file.getAbsolutePath());//获取文件的绝对路径
//3、创建、删除
file = new File("G:\\abc\\2.txt");
System.out.println( file.createNewFile());//新建文件2.txt
file = new File("G:\\abc\\M");
System.out.println( file.mkdir());//新建单层不存在的文件夹\M
file = new File("G:\\abc\\O\\P\\Q");
System.out.println( file.mkdirs());//新建多层不存在的文件夹O\\P\\Q
System.out.println( file.delete());//删除文件,删除空文件夹
//4、文件夹列表
file = new File("G:\\abc\\M");
String[] names = file.list();
//列出文件夹中的所有文件的名称
System.out.println(Arrays.toString(names));
File[] fs = file.listFiles();
//列出文件夹中的所有文件的文件对象
System.out.println(Arrays.toString(fs));
}
3、递归求目录总大小
//递归求目录总大小
public static void main(String[] args) {
//1.指定求哪个目录的总大小
File f=new File("G:\\a\\b");
//2.调用size方法 求目录大小
long l=size(f);//将这个目录传递给size方法,放到L中
System.out.println(l);
}
private static long size(File f) {
//1.列出目录下的所有资源listFiles();
File[] ls = f.listFiles();
long sum=0;
//2.遍历数组获取每个文件对象
for (int i = 0; i < ls.length; i++) {
File f1=ls[i];//ls[i]就是遍历到的每个文件对象啊
//3.拿到文件对象要判断啊
if (f1.isFile()) {//isFile()判断刚刚遍历的对象是不是文件
//是文件求文件字节量的大小
sum=f1.length()+sum;
}else if (f1.isDirectory()) {//isDirectory()判断刚刚遍历的对象是不是文件夹
//如果是文件夹,那就继续做刚刚相同的业务--方法的递归
sum=size(f1)+sum;
}
}
return sum;//把sum记录的值返回调用位置
}
4、递归删除文件
//递归删除文件夹
public static void main(String[] args) {
//1.指定想要删除的文件
File f=new File("G:\\a\\b");
del(f);//通过del方法完成业务
}
private static void del(File f) {
//1.列出文件下的所有资源listFlies()
File[] ls = f.listFiles();
//2遍历到每个资源,然后进行判断是否为空文件,或非空文件
for (int i = 0; i < ls.length; i++) {
File f1 = ls[i];//ls[i]就是遍历的每个文件
//3判断当前资源是文件夹还是文件
if (f1.isFile()) {
f1.delete();//是文件直接删除即可呀
}else if(f1.isDirectory()) {
//是文件夹的话,继续做刚刚相同的业务---方法的递归
del(f1);
}
}//4最后删除f文件即可(因为里面已经没有资源了--是空的)
f.delete();
}
}
二、IO字节流
java.io包:
字节流:针对二进制文件
一、 InputStream 字节流的读取流
是个抽象父类,不能创建对象,无法直接使用read()进行读取
(1、)FilelnputStream
InputStream的普通子类,创建子类对象使用read()进行文件的读取
private static void method() {
try {
1.创建字节流的读取对象
//InputStream是字节读取流的父类,是抽象类,不能new
//InputStream in=new InputStream() ;报错
InputStream in=new FileInputStream(new File("G://a//1.txt"));
InputStream in2=new FileInputStream("G://a//1.txt");
//这里创建对象右两种方式,一种是传入一个File形式,一种是String形式
2.开始读取,read()读取不到字节时会返回-1
int b;//定义变量记录读取到的数据
while ( (b = in.read()) != -1) {//有数据就一直读
System.out.println(b);
}
3.释放资源
in.close();
} catch (IOException e) {
e.printStackTrace();
(2、)BufferedInputStream
InputStream的高效读子类,创建子类对象使用read()进行文件的读取
new BufferedInputStream(new FilelnputStream(“D://****”))
(3、)ObjectInputStream
对象读取流,可以直接创建对象
二、OutputStream 字节流的写出流
是个抽象父类不能创建对象,无法直接使用write()进行写出
测试字节的写出OutputStream
//测试字节输出流
public static void main(String[] args) {
method();//使用普通的字节输出流对象输出数据FileOutputStream
}
private static void method() {
FileOutputStream out2 = null;//声明变量,因为finally要用
try {
//1.创建输出流对象。两种方式
//OutputStream out=new FileOutputStream(new File("G:\\abc\\2.txt"));
out2=new FileOutputStream("G:\\abc\\2.txt");
//2.利用OutputStream里的方法进行写出数据
out2.write(97);
} catch (IOException e) {
e.printStackTrace();
}finally {//保证代码一定会被执行,一定要放到finally里
try {
//3.释放资源
out2.close();
} catch (IOException e) {
e.printStackTrace();
}
(1、)FileOutputStream
OutputStream的普通子类,创建子类对象使用write()进行写出
(2、)BufferedOutputStream
OutputStream的高效写子类,创建子类对象使用write()进行写出
new BufferedOutputStream(new FileOutputStream(“D://****”),true)
效率问题:
为什么BufferedOutputStream > FiledOutputStream
因为:BufferedOutputStream底层维护了一个byte[ ],默认容量是8*1024字节,8K
不管是读取流还是写出流,Buffered底层维护了:---效率高
字符是char [ ]---------字节是byte[ ]
(3、)ObjectOutputStream
对象输出流,可以直接创建对象
三、IO字符流
字符流:针对文本文件
读写容易发生乱码现象,在读写时最好指定编码集为utf-8
一、Reader 字符读取流
是个抽象父类,不能创建对象,就无法直接使用read()进行读取
(1、)FileReader
Reader的子类,创建子类对象使用read()进行文件的读取
测试字符的读取Reader
//测试字符流的读取
public static void main(String[] args) throws IOException {
method();
method2();//高效字符流读取,
}
private static void method2() throws IOException {
Reader in3=new BufferedReader(new FileReader("D://a//c.txt"));
//BufferedReader是高效的读取对象,
//原因在于底层维护了一个char[],默认容量是8*1024 字节,就是8k
//以下操作和method()一样
}
private static void method() {
try {
//1.创建对象
//Reader in=new Reader();
//Reader是字符流读取对象的父类,但是是一个抽象类,不能new
Reader in=new FileReader(new File("D://a//c.txt"));
Reader in2=new FileReader("D://a//c.txt");
//2.开始读取
//定义一个变量记录读取的数据
int b;
while ( (b=in.read()) != -1 ) {//只要有数据就一直读
System.out.println(b);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
(2、)BufferedReader
Reader的高效子类,创建子类对象使用read()进行文件的读取
(3、)InputStreamReader
Reader的子类,创建子类对象使用read()进行文件的读取
二、Writer字符写出流
是个抽象父类不能创建对象,无法直接使用write()进行写出
测试字符输出流数据
//测试字符输出流数据--普通FileWriter
public static void main(String[] args) throws IOException{
Writer out =new FileWriter("D://a//t.txt",true);
out.write("hello");
out.write("java");
out.write(100);
out.close();
}
//测试字符输出流数据--高效BufferedWriter
public static void main(String[] args) throws IOException{
Writer out =new BufferedWriter(new FileWriter("D://a//t.txt",true));
out.write("hello");
out.write("java");
out.write(100);
out.close();
}
(1、)FileWriter
Writer的普通子类,创建子类对象使用read()进行文件的读取
(2、)BufferedWriter
Writer的普通子类,创建子类对象使用write()进行写出
(3、)InputStreamWriter
Writer的普通子类,创建子类对象使用read()进行文件的读取
读或写结束后一定要释放资源.close();
小结:
1.我们在io操作中会有大量的异常需要捕获,
2.字节读取(InputStream),利用子类创建对象,
其中又分普通子类 FileInputStream和高效BufferedIntputStream,
写出是OutputStream
3.字符读取(Reader),利用子类创建对象,
其中又分普通子类 FileReader和高效BufferedReader,写出是Write
4.在字节(OutputStream)、字符(Writer),写出时,
如果不想覆盖掉之前的数据,在创建对象时需要给出两个参数,
一个是文件的地址,一个是true值
文件的复制案例----这里展示的是字符流
文件的复制案例----这里展示的是字符流
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Scanner;
public class J {
//测试文件复制
public static void main(String[] args){
//开发思路:读取到源文件,写出到目标文件中
System.out.println("请输入源文件路径");
String f=new Scanner(System.in).nextLine();
File form=new File(f);
System.out.println("请输入目标路径");
String t=new Scanner(System.in).nextLine();
File to=new File(t);
copy(form,to);
}
private static void copy(File form, File to) {
Reader in=null;
Writer out=null;
try {
//1.读取form文件
in =new BufferedReader(new FileReader(form));
//2.写出到to文件
out =new BufferedWriter(new FileWriter(to));
//边读边写
int b;//定义变量,记录读取到的数据
while ((b=in.read()) != -1) {
out.write(b);//把b读到的资源写入out中
}
System.out.println("复制成功");
} catch (IOException e) {
System.out.println("复制失败");
e.printStackTrace();
}finally {
try {
//3.释放资源
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//3.释放资源
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
序列化、反序列化
序列化(Serialization):
是将对象的状态信息转换为可以存储或传输的形式过程。
把java中的一个对象存储起来,放在一个磁盘中,是一个写出的动作–out
序列化:
利用ObjectOutputStream,对象的信息,按固定格式转成一串字节值输出并持久保存到磁盘化。
反序列化: 利用ObjectInputStrean,读取磁盘中序列化数据,重新恢复对象
序列化/反序列化的特点-应用场景:
1.需要序列化的文件必须实现Serilizable接口 以启用其序列化功能
2.不需要序列化的数据可以被修饰为static的,由于static属于类,不随对象被序列化输出
3.不需要序列化的数据也可以修饰为transient 临时的,只在程序运行期间,在内存中存在不会被序列化持久保存
4.在反序列化时,如果和序列化的版本号不一致,无法完成反序列化。
5.每个被序列化的文件都有一个唯一id,如果没有添加编译器会根据类的定义信息计算生一个版本号
6.常用于服务器之间的数据传输,序列化成文件,反序列化读取数据。
7.常用于使用套接字流在主机之间传递对象
案例:
//测试序列化ObjectOutputStream
//序列化:是指把程序中的java对象永久保存在磁盘中 相当于是写出的过程,out---ObjectOutputStream
public static void main(String[] args){
try {
//1.创建序列化对象ObjectOutputStream
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("G:\\a\\1.tet"));
//2.指定要输入的对象
Student obj = new Student("jack",20,"北京");
out.writeObject(obj);
System.out.println("序列化完成");
} catch (IOException e) {
System.out.println("序列化失败");
e.printStackTrace();
}
//这个类用来描述学生类
//这个文件想要完成序列化必须实现可序列化接口,否则报错
public class Student implements Serializable{
/**
*给这个文件分配唯一的id值
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String addr;
//提供构造方法--右键Source-倒数第三个-ok
//提供公共的访问权限--重写get()...set()...
总结:
序列化就是通过java程序将对象里的值写出到磁盘中保存
1.文件想要完成序列化必须实现可序列化接口implements Serializable,实现后可以给这个文件分配唯一的id值
2.在main方法中.创建序列化对象ObjectOutputStream
ObjectOutputStream创建对象时,它的参数是它的子类new FileOutputStream(“G:\a\1.tet”)
3.然后指定要输入的对象,指定对象是ObjectOutputStream的一个方法writeObject(obj)
指定对象前,没有对象要创建对象
Student obj = new Student(“jack”,20,“北京”);
out.writeObject(obj);将obj写出到out里
案例:
//测试反序列化ObjectInputStream
//反序列化:是指把已经序列化好的文件保存的数据,读取/恢复到java程序的过程,in---ObjectInputStream
public static void main(String[] args){
try {
//1.创建反序列化对象ObjectInputStream
ObjectInputStream in=new ObjectInputStream(new FileInputStream("G:\\a\\1.tet"));
//2.开始读取
Object o = in.readObject();
System.out.println(o);//默认打印了对象的地址值,是用了Object提供的toStrig(),需要在要读取的类里重写toString()
System.out.println("反序列化完成");
in.close();//释放资源
} catch (IOException e) {
System.out.println("反序列化失败");
e.printStackTrace();
}
//这个类用来描述学生类
//这个文件想要完成反序列化必须实现可序列化接口,否则报错
public class Student implements Serializable{
/**
*给这个文件分配唯一的id值
*/
private static final long serialVersionUID = 1L;
//提供构造方法--右键Source-倒数第三个-ok
//提供公共的访问权限--重写get()...set()...
//重写toString()
private String name;
private int age;
private String addr;
总结:反序列化是指把已经序列化好的文件保存的数据,读取/恢复到java程序的过程,in---ObjectInputStream
1.文件想要完成反序列化必须实现可序列化接口implements Serializable,实现后可以给这个文件分配唯一的id值
2.在main方法中.创建反序列化对象ObjectInputStream
ObjectInputStream创建对象时,它的参数是它的子类new FileInputStream("G:\\a\\1.tet")
3.然后就可以读取了,读取方法是ObjectInputStream的一个方法readObject()返回值是一个Object对象
Object o = in.readObject();
4.然后直接打印o就可以了,这里注意默认打印了对象的地址值,是用了Object提供的toStrig(),需要在要读取的类里重写toString()
编码转换流
用来作为桥梁,把字节流转成字符流
用来解决字符流读写乱码问题
工具类:
OutputStreamWriter:是字节流转向字符流的桥梁
OutputStreamWriter(OutputStream out,String charsetName)
OutputStreamWriter(OutputStream out)
InputStreamReader:是字节流通向字符流的桥梁
InputStreamReader(InputStream in)
案例;
//测试编码转换流
public static void main(String[] args){
try {
//测试写出的编码转换流:OutputStreamWriter,用来把字节流转成字符流
//1.创建OutputstreamWriter对象
OutputStreamWriter out=new OutputStreamWriter(new FileOutputStream("1.txt"),"gbk");
//txt不是磁盘的路径,就会在同级src下创建(需要按f5刷新出来)
//默认编码是gbk,也可以传入两个参数,第二个参数可以指定编码集
//2.写出数据
out.write("abc");
//3.释放资源
out.close();
} catch (Exception e) {
e.printStackTrace();
}