File 类
表示要读写的文件在哪,也可以对文件/文件夹进行创建和删除等。
1. File 类的概述和构造方法
-
概述
- File是文件和目录路径名的抽象表示
- 文件和目录可以通过File封装成对象
- 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也可以是不存在的
-
构造方法
方法名 说明 File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例 File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例 public class FileDemo01 { public static void main(String[] args) { File file = new File("F:\\IOfile\\a.txt"); System.out.println(file);//F:\IOfile\a.txt } }
2. 绝对路径和相对路径
- 绝对路径
- 从盘符开始的,一个完整的路径
- 相对路径
- 相对当前项目下的路径
3. File 类创建功能
-
方法
方法名 说明 注意 public boolean createNewFile() 创建一个新的空的文件 1.如果文件存在,那么创建失败,返回false;
2.如果文件不存在,那么创建成功,返回true;
3. 不管调用者有没有后缀名,只能创建文件
4. 创建文件所在的文件夹必须存在public boolean mkdir() 创建一个单级文件夹 1. 只能创建单级文件夹,不能创建多级文件夹
2. 不管调用者有没有后缀名,只能创建单级文件夹public boolean mkdirs() 创建一个多级文件夹 1. 可以创建单级文件夹,也可以创建多级文件夹
2. 不管调用者有没有后缀名,只能创建单级文件夹 -
代码
public class FileDemo02 { public static void main(String[] args) throws IOException { File file = new File("F:\\IOfile\\b.txt"); //如果没有当前要创建的文件,就返回true,有就返回false boolean newFile = file.createNewFile(); System.out.println(newFile);//true File file1 = new File("F:\\IOfile\\a\\b\\c"); boolean mkdirs = file1.mkdirs(); System.out.println(mkdirs);//true } }
4. File类 删除功能
-
方法
方法名 说明 注意 public boolean delete() 删除由此抽象路径名表示的文件或目录 1. 删除文件是不走回收站的
2. 如果删除的是文件,直接删除
3.如果删除的是文件夹,那么只能删除空文件夹
4.如果要删除一个有内容的文件夹,只能先把文件夹的内容全删除,再删除文件夹
5. File 类判断和获取功能
-
判断方法
方法名 说明 public boolean isDirectory() 测试此抽象路径名表示的File是否为目录 public boolean isFile() 测试此抽象路径名表示的File是否为文件 public boolean exists() 测试此抽象路径名表示的File是否存在 -
获取方法
方法名 说明 注意 public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串 public String getPath() 将此抽象路径名转换为路径名字符串 public String getName() 返回由此抽象路径名表示的文件或目录的名称 public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组 1. 当调用者是一个有内容的文件夹时,进入文件夹获取这个文件夹里面所有的文件和文件夹的file对象,并把这些file对象都放在一个数组中返回,包括隐藏文件和隐藏文件夹都可以获取
2. 当调用者是一个文件时,返回的数组是为null
3. 当调用者是一个空文件夹时,会返回一个长度为0的数组
4.当调用者是一个需要权限才能进入的文件夹时,会返回null
5. 当调用者不存在时候,返回null -
小栗子1
public class FileDemo03 { public static void main(String[] args) throws IOException { File file = new File("F:\\IOfile"); File[] files = file.listFiles(); for (File path : files) { if (path.isDirectory()){ System.out.println(path.getName()+"是文件夹"); }else if (path.isFile()){ System.out.println(path.getName()+"是一个文件"); } } } } //Output: // a是文件夹 // a.txt是一个文件 // b.txt是一个文件
-
小栗子2:删除一个多级文件夹
public class FileDemo04 { public static void main(String[] args) throws IOException { File file = new File("F:\\IOfile"); deleteDir(file); } private static void deleteDir(File file) { //1.进入该路径的文件夹 File[] files = file.listFiles(); //2.遍历里面的内容 for (File path : files) { if (path.isFile()){ //3.判断是文件的话就直接删除 path.delete(); }else if (path.isDirectory()){ //4.是文件夹的话就递归 deleteDir(path); } } //5. 最后删除自己 file.delete(); } }
-
小栗子3:统计一个文件夹中各类文件的个数
public class FileDemo05 { public static void main(String[] args) throws IOException { File file = new File("day11_IO"); HashMap<String,Integer> hm = new HashMap<>(); getcount(file,hm); System.out.println(hm); } private static void getcount(File file,HashMap<String,Integer> hm) { //1. 进入这个路径的文件夹 File[] files = file.listFiles(); //2.遍历 for (File path : files) { //判断是文件还是文件夹 if (path.isFile()){ //获取文件路径的文件名 String fileName = path.getName(); // System.out.println(fileName); //以 . 为分隔成数组 String[] split = fileName.split("\\."); //判断长度是否为2,如果是2,前面就是文件名,后面就是文件类型 if (split.length == 2){ String key = split[1]; //判断当前集合中是否有该文件名为key的值 if (hm.containsKey(key)){ //如果有,就将其值+1,再重新添加一次 Integer count = hm.get(key); //map的赋值,key相同的话会覆盖掉旧的值 hm.put(key,++count); }else { //如果没有,那么表示该文件类型是第一次出现, //就存进去集合,初始值为1 hm.put(key,1); } } }else { //是文件夹的话,就递归调用 getcount(path,hm); } } } } //字符串中存在 . 和 | 的时候, // 不能直接用String.split(".")进行分隔, // 而是String.split("\\ .")或者String.split("\\ |"); //因为直接写的话系统是无法识别的,需要通过转义符
IO 流
1. 概述和分类
- 概述
- I :表示intput,是数据从硬盘进内存的过程,称之为读
- O :表示output,是数据从内存到硬盘的过程,称之为写
- 流:一种数据的流动(数据传输)
- 分类
- 按流向分:
- 输入流
- 输出流
- 按数据类型分
- 字节流:可以操作所有类型的文件,包括图片视频等等
- 字符流:只能操作纯文本文件,例如java文件,txt文件等等
- 能用windows记事本打开读懂的文件,才是纯文本文件
- 按流向分:
2. 字节流
-
字节流抽象基类
- InputStream:这个抽象类是表示字节输入流的所有类的超类
- OutputStream:这个抽象类是表示字节输出流的所有类的超类
- 子类名特点:子类名称都是以其父类名作为子类名的后缀
-
字节输出流
- FileOutputStream(String name):创建文件输出流以指定的名称写入文件
-
字节流写数据
-
创建直接输出流对象
FileOutputStream fos = new FileOutputStream(File对象/String类路径);
-
注意:
如果文件不存在,会帮我们自动创建出来
如果文件存在,会把文件清空
-
-
写数据
fos.write(97);
-
注意:
传递一个整数时,那么实际上写到文件中的是这个整数在码表中对应的字符
-
-
释放资源
fos.close();
- 告诉系统不再使用这个资源了
- 每次使用完流必须要释放资源
-
-
写数据的三种方式
方法名 说明 void write(int b) 将指定的字节写入此文件输出流 一次写一个字节数据 void write(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据 void write(byte[] b, int off, int len) 从off索引开始,写len个元素 -
小栗子
public class IODemo02 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("F:\\IOfile\\a.txt"); byte[] bys = {97,98,99,100,101,102}; fos.write(bys); fos.write(bys,2,2); fos.close(); } }
-
如何实现换行
加换行符:
- windows:\r\n
- linux:\n
- mac:\r
使用String类中的getBytes方法,返回一个byte数组
-
如何实现追加写入
- public FileOutputStream(String name,boolean append)
- 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头
-
加入trycatch异常处理
-
finally
被finally控制的语句,一定会执行
-
小栗子
public class IODemo04 { public static void main(String[] args) { FileOutputStream fos = null; try { fos = new FileOutputStream("day11_IO\\a.txt",true); String s = "\r\n123456"; fos.write(s.getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { if (fos!=null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
-
-
字节流读数据
-
直接输入流
FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名
-
步骤
- 创建字节输入流对象
- 如果文件存在不会报错
- 如果文件不存在,那么就直接报错
- 调用字节输入流对象的读数据方法(read)
- 一次读取一个字节,返回值就是本次读到的那个字节数据,是码表中对应的数据
- 释放资源(close)
- 创建字节输入流对象
-
-
一次读多个字节
public class IODemo05 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("day11_IO\\a.txt"); int b ; while ((b = fis.read())!=-1){ System.out.println((char)b); } fis.clos(); } }
-
复制文件
public class IODemo06 { public static void main(String[] args) throws IOException { //创建字节输入流,将文件读进来 FileInputStream fis = new FileInputStream("F:\\IOfile\\a.txt"); //创建字节输出流,将输入流的读进来的数据写出去 FileOutputStream fos = new FileOutputStream("day11_IO\\a.txt",true); int b ; while ((b = fis.read())!=-1){ fos.write(b); } fis.close(); fos.close(); } }
-
用字符数组加快复制的速度
public static void main(String[] args) throws IOException { //创建字节输入流,将文件读进来 FileInputStream fis = new FileInputStream("E:\\素材\\嘿嘿嘿.avi"); //创建字节输出流,将输入流的读进来的数据写出去 FileOutputStream fos = new FileOutputStream("day11_IO\\嘿嘿嘿.avi"); byte[] bys = new byte[1024]; int len ; //读入缓冲区的总字节数,如果由于文件末尾已到达而没有更多数据, -1 。 while ((len = fis.read(bys))!=-1){ //从此输入流b.length最多b.length个字节的数据读入一个字节数组。 // 此方法将阻塞,直到某些输入可用。 fos.write(bys,0,len); } fis.close(); fos.close(); } }
-
字节缓冲流
- BufferOutputStream:字节缓冲输出流
- BufferInoutStream:字节缓冲输入流
-
构造方法
方法名 说明 BufferedOutputStream(OutputStream out) 创建字节缓冲输出流对象 BufferedInputStream(InputStream in) 创建字节缓冲输入流对象 -
小栗子
public class IODemo07 { public static void main(String[] args) throws IOException { //在底层创建了一个默认长度为8192的字节数组 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\ooo.avi")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11_IO\\copy.avi")); int b ; while ((b = bis.read())!=-1){ bos.write(b); } //方法的底层会把字节流关闭 bis.close(); bos.close(); } }