一、File类
- 1.概述:java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。
- 2.构造方法:
- public File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的File实例。
- public File(String parent, String child) :从⽗路径名字符串和⼦路径名字符串创建新的File 实例。
- public File(File parent, String child) :从⽗抽象路径名和⼦路径名字符串创建新的 File实例。
- `//文件路径名
- File file=new File(“aa/bb.txt”);
- //通过父路径和子路径字符串
- String parent=“d:\\aaa”
- String child="bbb.txt";
- File file=new File(parent,child);`
**小提示:
- ⼀个File对象代表硬盘中实际存在的⼀个⽂件或者⽬录。
- ⽆论该路径下是否存在⽂件或者⽬录,都不影响 File 对象的创建。**
拓展:绝对路径和相对路径
绝对路径:从盘符开始的路径,这是⼀个完整的路径。
相对路径:相对于项⽬⽬录的路径,这是⼀个便捷的路径,开发中经常使⽤。
//D盘下的bbb.java文件
File f=new File("D:\\bbb.java");
// 项⽬下的bbb.java⽂件
File f2 = new File("bbb.java");
3.常用方法
3.1获取功能的方法
public String getAbsolutePath() :返回此File的绝对路径名字符串。
public String getPath() :将此File转换为路径名字符串。
public String getName() :返回由此File表示的⽂件或⽬录的名称。
public long length() :返回由此File表示的⽂件的⻓度。
小提示:API中说明:length(),表示⽂件的⻓度。但是File对象表示⽬录,则返回值未指定。
3.2判断功能的方法
public boolean exists() :此File表示的⽂件或⽬录是否实际存在。
public boolean isDirectory() :此File表示的是否为录。
public boolean isFile() :此File表示的是否为⽂件。
3.3创建和删除功能的方法
public boolean createNewFile() :当且仅当具有该名称的⽂件尚不存在时,创建⼀个新的空⽂件。
public boolean delete() :删除由此File表示的⽂件或⽬录。
public boolean mkdir() :创建由此File表示的⽬录。
public boolean mkdirs() :创建由此File表示的⽬录,包括任何必需但不存在的⽗⽬录。
3.4目录的遍历
public String[] list() :返回⼀个String数组,表示该File⽬录中的所有⼦⽂件或⽬录。
public File[] listFiles() :返回⼀个File数组,表示该File⽬录中的所有的⼦⽂件或⽬录。
public static void main(String[] args) {
File file = new File("cc");
deleteDir(file);
}
public static void deleteDir(File dir){
//1.列出dir目录中全部的文件对象
File[] files = dir.listFiles();
if(files!=null||files.length!=0){
//2.循环删除每一个文件对象
for(File f:files){
if(f.isDirectory()){
deleteDir(f);//递归
}else {
f.delete();
}
}
}
//3.dir是空目录了,删除
dir.delete();
}
二、io流
2.1 io概述:
IO,即in和out,也就是输入和输出,指应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络连接。
Java中I/O操作主要是指使⽤ java.io 包下的内容,进⾏输⼊、输出操作。输⼊也叫做读取数据,输出也叫做作写出数据。
java中是通过流处理IO的,那究竟什么是流?
流(stream),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息通道,每个流只能是输入流或输出流的一种,不能同时具备两个功能。
2.1.1流的父子类关系
字节流的父类:InputStream/OutputStream
字符流的父类:Reader/Writer
字节流的普通子类:FileInputStream/FileOutputStream
字符流的普通子类:FileReader/FileWriter
带缓冲区的字节流:BufferedInputStream/BufferedOutputStream
带缓冲区的字符流BufferedReade/BufferedWriter(打印流)
转换流:InputStreamReader/OutputStreamWriter
InputStreamReader OutputStreamWriter是转换流
InputStreamReader 是字节流通向字符流的桥梁,它将字节流转换为字符流.(面向字符)
OutputStreamWriter是字符流通向字节流的桥梁,它将字符流转换为字节流.(面向字符)
//转化流用法
FileInputStream fs= new FileInputStream("out.txt");
InputStreamReader gbk = new InputStreamReader(fs, "GBK");
BufferedReader bf = new BufferedReader(gbk);
IO流各个父子类的关系图
小提示:一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。
2.2 io的分类
(1).根据数据的流向分为:输入流和输出流。
- 输⼊流 :把数据从 其他设备 上读取到 内存 中的流。
- 输出流 :把数据从 内存 中写出到 其他设备 上的流。
(2).格局数据的类型分为:字节流和字符流。
- 字节流 :以字节为单位,读写数据的流。(8位的字节)
- 字符流 :以字符为单位,读写数据的流。
(16位的字符,在UTF-8编码中,一个中文字符是3个字节,在GBK编码中,一个中文字符是2个字节)
字节流特点: 用字节进行读/写操作,通常用来复制文件,最常使用缓冲(具有缓冲功能的子类,缓冲功能可以提升运行效率)+数组(通常new byte[])进行搭配使用,字节流一般用来处理图像、视频、音频、PPT、Word等类型的文件。
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("1.png");
FileOutputStream fos = new FileOutputStream("p3.png");
long start=System.currentTimeMillis();
int i;
byte[] bs = new byte[1024];
while ((i=fis.read(bs))!=-1){
fos.write(bs,0,i);
}
long end=System.currentTimeMillis();
fis.close();
fos.close();
System.out.println(end-start);
/* int j;
while ((j=fis.read())!=-1){
fos.write(j);
}
fis.close();
fos.close();*/
}
**字符流特点:**用字符进行读/写操作,通常用来读/写文本内容,只能单独(多个)的字符读取(如果想一次读一行,则需要用到BufferedReader这个子类),字符流一般用于处理纯文本类型的文件,如TXT文件等,但不能处理图像视频等非文本文件。
字节流和字符流的区别:
- 字节流可以处理一切文件,而字符流只能处理纯文本文件。
- 字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高。而字符流本身就带有缓冲区,缓冲字符流相对于字符流效率提升就不是那么大了。
字节流提升效率的方法: 使用Buffered这个缓冲流,具体代码如下:``
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("p3.png");
FileOutputStream fos = new FileOutputStream("p4.png");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
long start=System.currentTimeMillis();
byte[] bt=new byte[1024];
int i;
while ((i=bis.read(bt))!=-1){
bos.write(bt,0,i);
}
bis.close();
bos.close();
fis.close();
fos.close();
long end=System.currentTimeMillis();
System.out.println("运行时间:"+(end-start));
}
节点流和处理流
节点流: 直接操作数据读写的流类,比如FileInputStream
处理流: 对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能,例如BufferedInputStream(缓冲字节流)
为什么会有缓冲流
我们知道,程序与磁盘的交互相对于内存运算是很慢的,容易成为程序的性能瓶颈。减少程序与磁盘的交互,是提升程序效率一种有效手段。缓冲流,就应用这种思路:普通流每次读写一个字节,而缓冲流在内存中设置一个缓存区,缓冲区先存储足够的待操作数据后,再与内存或磁盘进行交互。这样,在总数据量不变的情况下,通过提高每次交互的数据量,减少了交互次数。
文件里存放对象(属性,值)
对象流: ObjectInputStream(父类readObject() )/ObjectOutputStream(父类writeObject())
写入文件内:
public static void main(String[] args) throws IOException {
Person p = new Person("张三丰", 18);
FileOutputStream fos = new FileOutputStream("out.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p);
oos.close();
}
从文件内读取:
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("out.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Person o = (Person) ois.readObject();
ois.close();
System.out.println(o);
}
可能会遇到的异常
NotSerializableException: 不是可序列化的, 需要添加可序列化接口
Serializable: 接口内容 无
InvalidClassException: 不兼容的类型, 需要添加版本号来固定版本
public static final long serialVersionUID=唯一
transient: 临时属性, 不会写入到文件中