文件API及其操作

发布于:2024-05-04 ⋅ 阅读:(118) ⋅ 点赞:(0)

这里介绍两类文件操作、三个文件类。包括文件系统操作(File类)、文件内容操作(操作字节流、操作字符流)

1.文件类File

1.1.认识File类

(1)什么是File类呢?其实就是可以操作文件的一个类。通过File类构造一个文件对象,此时就得到了一个文件对象的引用,通过该引用,可以得到该文件的路径、名字;判断该文件对象是文件目录还是目标文件

(2)构造方法

签名 说明
File(File parent,String child) 根据父目录+孩子文件路径,创建一个新的File实例
File(String pathname) 根据文件路径创建一个新的File实例,路径可以是绝对/相对路径
File(String parent,String child) 根据父目录+孩子文件路径,创建一个新的File实例,父目录用路径表示

我们常用第二个,pathname就是一个文件路径,绝对路径或者相对路径都可以。

值得注意的点:以上创造的File对象,里面的文件路径,表示的是目录还是最终文件,无论在你的硬盘中是否存在,都不影响,都可以创造出来。

1.2.认识File类的方法

这个有什么用呢?就是在构建好一个文件对象之后,可以通过File类中的方法去操作文件。

(1)返回路径型

返回值类型 方法签名 说明
String getParent() 返回File对象的父目录文件路径
String getName() 返回File对象的纯文件名称
String getPath() 返回File对象的文件路径
String getAbsolutePath() 返回File对象的绝对路径
String getCanonicalPath() 返回File对象的修饰过的绝对路径

(2)返回boolean型

返回值类型 方法签名 说明
boolean exists() 判断File对象描述的文件是否真实存在
boolean isDirectory() 判断File对象代表的文件是否是一个目录
boolean isFile() 判断File对象代表的文件是否是一个普通文件
boolean createNewFile() 根据File对象,自带创建一个空文件。成功创建后返回true
boolean delete() 根据File对象,删除该文件。成功删除后返回true
boolean mkdirs() 创建File对象代表的目录,如果必要,会创建中间目录
boolean renameTo(File dest) 进行文件改名,也可以视为我们平时的剪切、粘贴操作

(3)其他类型

返回值类型 方法签名 说明
void deleteOnExit() 根据File对象,标注文件将删除,删除动作会到JVM运行结束时
String[ ] list() 返回File对象代表的目录下的所有文件名
File[ ] listFiles() 返回File对象代表的目录下的所有文件,以File对象表示

在标准库中,还有许多方法,这里就不一一展示了。

很多方法在后续也都会使用到,这里也不做使用的展示,我们接着看后续。

1.3.实例化文本对象

下面介绍三种创造File对象的方式,可以说是不同的情况创造File对象 

(1)文件不存在-以相对路径

这个test666.txt文件在实例化对象时,是不存在的,所以最后一行是显示false。其他的路径是因为我们在创造的时候是以一个相对路径,相对路径的现在位置就是该.java文件的位置。

 public static void main(String[] args) throws IOException {
        File f = new File("./text666.txt");
        System.out.println("该文件名字:"+f.getName());
        System.out.println("这级目录的名字:"+f.getParent());
        System.out.println("文件的路径:"+f.getPath());
        System.out.println("文件的绝对路径:"+f.getAbsolutePath());
        System.out.println("文件的绝对路径2:"+f.getCanonicalPath());//这个需要抛出异常
        System.out.println("文件是否真是存在:"+f.exists());
    }

(2)文件不存在--以绝对路径

(3)文件存在--以绝对路径

我们先在d盘上面创造一个文件

然后以创造文件类的方式打开

 public static void main(String[] args) throws IOException {
        File f = new File("d:/test999.txt");
        System.out.println("该文件名字:"+f.getName());
        System.out.println("这级目录的名字:"+f.getParent());
        System.out.println("文件的路径:"+f.getPath());
        System.out.println("文件的绝对路径:"+f.getAbsolutePath());
        System.out.println("文件的绝对路径2:"+f.getCanonicalPath());//这个需要抛出异常
        System.out.println("文件是否真是存在:"+f.exists());
    }

然后以相对路径打开:

第一个绝对路径就是当前的基准路径(在当前项目运行代码)+相对路径拼接而成

绝对路径2就是:拼接后并进行了一些优化操作。

1.4.创造文件

如果文件不存在,我们创造文件要根据下面的方法 

 

(1)相对路径创造文件

 public static void main(String[] args) throws IOException {
        File f = new File("./test222.txt");
        f.createNewFile();//需要抛出异常
    }

需要抛出异常的原因:(1)给出的路径非法(2)路径权限不足

(2)以绝对路径创造

public static void main(String[] args) throws IOException {
        File f = new File("d:/tttttt.txt");
        boolean bool = f.createNewFile();
        System.out.println(bool);
    }

程序运行后:

文件被真正的创造了出来,如果再运行一次代码,就是返回false,原因是该文件已经存在,无法再创造。

(3)判断文件是目录还是普通文件

 public static void main(String[] args) throws IOException {
        File f = new File("d:/tttttt.txt");
        f.createNewFile();
        System.out.println("文件是否真实存在:"+f.exists());
        System.out.println("文件是否代表目录:"+f.isDirectory());
        System.out.println("文件是否为普通问题:"+f.isFile());
    }

1.5.删除文件

删除文件有两个方法,下面一一介绍如果使用,及使用后的结果。

(1)直接删除文件

 public static void main(String[] args) throws IOException {
        File f = new File("d:/tttttt.txt");
        f.createNewFile();
        boolean bool = f.delete();
        System.out.println(bool);
    }

文件已被删除。

(2)延迟删除

 public static void main(String[] args) throws IOException {
        File f = new File("d:/tttttt.txt");
        f.createNewFile();
        f.deleteOnExit();//等进程结束后再删除文件
        System.out.println("进程结束前"+f.exists());
        Scanner in = new Scanner(System.in);
        in.next();//阻塞进程结束
        System.out.println("进程结束后:"+f.exists());
    }

当输入后,进程就会马上结束

文件也就不存在了。这就是延迟删除,当程序彻底结束后文件才会被删除。

接下来的部分是针对文件的内容进行操作。 操作文件内容的三个固定步骤:以二进制/文本方式打开文件--->读文件/写文件--->关闭文件

2.字节流

这样的意思就是:以二进制的方式打开文件,以字节为单位进行读取数据/写数据。

2.1.以字节流读取文件

所谓读取文件,就是读取文件中的数据,但是不会改变里面的内容

(1)打开文件

要读取数据,第一步就是打开文件。这里需要使用两个类,实例化好了对象,就相当于拿到了一个“流”对象,通过流,就可以随时读取文件数据。

 InputStream file = new FileInputStream("d:/dog111.txt");//以二进制打开文件(文件必须存在)

使用到两个类:

InputStream//抽象父类
FileInputStream//子类

注意点:

1)文件路径代表的文件必须真实存在,否则会抛出异常

2)必须在方法后面声明异常

(2)读取文件内容

打开了文件,接下来就读取文件内容的操作,读取文件内容有下面三种方式:

返回值类型 方法签名 说明
int read() 读取一个字节的数据,返回-1代表读取结束(内容已读取完)
int read(byte[ ] b) 最多读取b.length字节的数据到b中,返回时机读到的数量;-1代表读取完
int read(byte[ ],int off,int len) 最多读取len-off个字节到b中,从b的off位置开始存放;-1读取完

第一种读取方式:每次读取一个字节

 public static void main(String[] args) throws IOException {
        //1.打开文件
        InputStream file = new FileInputStream("d:/dog111.txt");//以二进制打开文件(文件必须存在)
        //2.读文件
        while (true) {
            int n = file.read();
            if(n==-1) {
                System.out.println("文件读取完毕");
                break;
            }
            System.out.printf("%d ",n);
        }

    }

运行结果 

文件内容:

代码解释:我们采取循环读取的方式进行读取,当读取到-1的时候,说明文件里面的内容都已经被读取完毕了,就可以结束循环。

第二种读取方式:每次读取一个字节数组的数据

 public static void main(String[] args) throws IOException{
        InputStream file = new FileInputStream("d:/dog111.txt");
        byte[] bytes = new byte[1024];
        while (true) {
            int n = file.read(bytes);
            if(n==-1) break;
            for (int i = 0; i < n; i++) {
                System.out.printf("%c ",bytes[i]);
            }
            System.out.println();
        }
    }

这种方法读取数据会比第一种快,而且效率也高,

第三种方式:特定场景使用

 public static void main(String[] args) throws IOException{
        InputStream inputStream = new FileInputStream("d:/dog111.txt");
        byte[] bytes = new byte[1024];
        while (true) {
            int n = inputStream.read(bytes,0,1024);
            if(n==-1) {
                break;
            }
            for (int i = 0; i < n; i++) {
                System.out.printf("%c ",bytes[i]);
            }
        }

    }

上述都只是打开了流和读取数据,并没有关闭流,下面介绍关闭流。

2.2.关闭流

第一种方式:

使用try finally,目的是防止程序发生特殊情况,导致没有关闭流。但是这样子冗余,不好看。

 public static void main(String[] args) throws IOException{
        InputStream inputStream = new FileInputStream("d:/dog111.txt");
       try{
           byte[] bytes = new byte[1024];
           while (true) {
               int n = inputStream.read(bytes,0,1024);
               if(n==-1) {
                   break;
               }
               for (int i = 0; i < n; i++) {
                   System.out.printf("%c ",bytes[i]);
               }
           }
       }finally {
           inputStream.close();
       }

    }

第二种方式:

 public static void main(String[] args) throws IOException{
        try (InputStream file = new FileInputStream("d:/dog111.txt")){
            byte[] bytes = new byte[1024];
            while (true) {
                int n = file.read(bytes);
                if(n==-1) break;
                for (int i = 0; i < n; i++) {
                    System.out.print((char) bytes[i]+" ");
                }
            }
        }
    }

将打开流的操作,放在try中。当执行完后,会自动关闭流,也就不不需要在后面加上finally了

2.3.以字节流写文件

 (1)第一次写

public static void main(String[] args)  throws IOException{
        //写文件
        try(OutputStream outputStream = new FileOutputStream("d:/dog111.txt")) {
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
            outputStream.write(100);
            outputStream.write(101);
        }
    }

再写一次:

第二次写时会覆盖掉文件内的内容。

原因是:打开文件就会把文件原有的内容给覆盖掉。为了解决这个问题,可以使用追加的方式进行打开文件。

3.字符流

接下来的读取/写文件,都是以字节为单位的。 

3.1.读文件

对于读文件,依旧是有三种方式,和上述的字节流类似

 (1) 第一种方式:

 public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("d:/dog111.txt");
        while (true) {
            int n = reader.read();
            if(n==-1) break;
            System.out.print((char)n+" ");
        }
    }

可以读取文字

当去read()的时候,读到的是三个字符的数据,但是返回的时候,会转化成两个字节去接收。

(2)第二种方式: 

3.2.写文件

写文件,和上述是一样的。

 如果直接打开文件,然后去写文件,就会将原有的内容覆盖,所以要使用追加的方式去写。

(1)不追加写

原有内容被覆盖了。也就是第一次写入的时候,接着往下写是不会被覆盖的。

(2)追加写


网站公告

今日签到

点亮在社区的每一天
去签到