Java文件IO操作

目录

什么是文件?

文件的分类 

文件的路径表示 

Java对于文件的操作 

File中的一些普通方法 

Java对文件内容的操作(读和写)  

文件操作字节流 

FileInputStream(文件输入流)(读)继承自InputStream

read方法 

read无参数 

read有参数(byte数组)

FileOutputStream(文件输出流) (写)继承自OutputStream

write方法 

close方法 

优雅的close写法 

close放到finally中 

Java中更优雅的写法:(将对象写在try的括号里面)

文件操作字符流 

FileReader(输入)读 继承自 Reader

FileWriter(输出)写 继承自 Writer 


 

什么是文件?

狭义的文件指的是计算机硬盘上的文件和目录。

比如:

Java文件IO操作_第1张图片

广义的文件是指计算机中的软硬件资源。

文件的分类 

文件可以分为两种类型,一种是文本型,一种是二进制型。

如何判断是什么类型的文件呢?可以使用记事本,把文件拖到记事本里面,如果能够看懂就是文本的,如果出现有乱码就属于二进制类型的文件 

文件的路径表示 

文件的路径表示可以分为两种,一种是绝对路径,一种是相对路径。

比如Tencent这个文件夹,他的绝对路径就是C:\temp\Tencent 

Java文件IO操作_第2张图片

需要注意的是Windows当中文件路径可以使用\(反斜杠)和/(正斜杠)来作为分隔符,但是在写代码的时候我们建议还是使用/正斜杠来作为分隔符,因为\反斜杠容易被当成转义字符。

如果我们当前在C:\temp下,那么Tencent的相对路径就是./Tencent。

./表示当前目录(也就是C:\temp)

当我们进入到Tencent目录下,此时Tencent的相对路径就变成了../Tencent

Java文件IO操作_第3张图片

../是上一级目录的意思 

Java对于文件的操作 

Java对于文件的操作分为两类:

1、对文件的系统操作(比如删除,创建,重命名等等) 

2、对文件内容的操作(读和写) 

Java对文件的操作主要是用到File这个类 

File这个类有三个构造方法:

Java文件IO操作_第4张图片

其中最常用的是File(string pathname)这个方法。

        File file=new File("c:/testDemo");

需要注意的是,file中的路径不代表这个文件是否存在,如果不存在,也不会进行创建文件。 

创建文件需要掉用mkdir方法来创建,如果文件已经存在,再次是用mkdir是不会影响原来的文件的,也不会重新建,也不会覆盖。

File中的一些普通方法 

修饰符及返回
值类型
方法签名 说明
String getParent() 返回 File 对象的父目录文件路径
String getName() 返回 FIle 对象的纯文件名称
String getPath() 返回 File 对象的文件路径
String getAbsolutePath() 返回 File 对象的绝对路径
String getCanonicalPath() 返回 File 对象的修饰过的绝对路径
boolean exists() 判断 File 对象描述的文件是否真实存在
boolean isDirectory() 判断 File 对象代表的文件是否是一个目录
boolean isFile() 判断 File 对象代表的文件是否是一个普通文件
boolean createNewFile() 根据 File 对象,自动创建一个空文件。成功创建后返
回 true
boolean delete() 根据 File 对象,删除该文件。成功删除后返回 true
void deleteOnExit() 根据 File 对象,标注文件将被删除,删除动作会到
JVM 运行结束时才会进行
String[] list() 返回 File 对象代表的目录下的所有文件名
File[] listFiles() 返回 File 对象代表的目录下的所有文件,以 File 对象
表示
boolean mkdir() 创建 File 对象代表的目录
boolean mkdirs() 创建 File 对象代表的目录,如果必要,会创建中间目
boolean renameTo(File
dest)
进行文件改名,也可以视为我们平时的剪切、粘贴操
boolean canRead() 判断用户是否对文件有可读权限
boolean canWrite() 判断用户是否对文件有可写权限

这些方法也不需要背,用的时候找到就可以了。 

下面是一些示例:

package io;

import java.io.File;
import java.io.IOException;

public class IODemo1 {
    public static void main(String[] args) throws IOException {
        File file=new File("c:/testDemo");//file对象
        System.out.println(file.getName());//获取到文件的名称
        System.out.println(file.getPath());//获取到文件的路径
        System.out.println(file.isFile());//判断文件是否是普通文件,而不是目录
        System.out.println(file.getParent());//获取file对象的父目录路径
        System.out.println(file.getAbsolutePath());//获取绝对路径
        System.out.println(file.getCanonicalPath());//获取修饰过后的绝对路径
        System.out.println(file.exists());//判断当前文件是否存在
        if(!file.exists()){
            //如果文件不存在,就进行文件的创建
            file.mkdir();
        }

    }
}

Java文件IO操作_第5张图片

我们可以看到,之前没有的文件,现在可以在该目录下找到,说明已经创建了。

Java文件IO操作_第6张图片

需要注意的是我们使用IDEA的时候,如果我们创建的文件是相对路径的话,那么该文件的父路径就是项目所在的路径:

package io;

import java.io.File;

public class IDDemo2 {
    public static void main(String[] args) {
        File file=new File("./IOTest");
        file.mkdir();//mkdir只能用来创建一级目录
        
    }
}

Java文件IO操作_第7张图片

当我们需要创建多级目录的时候,就不能使用mkdir方法,而是使用mkdirs()。

比如我们要在IOTestDemo1目录下面再创建个aaa文件:

package io;

import java.io.File;

public class IDDemo2 {
    public static void main(String[] args) {
        File file=new File("./IOTestDemo1/aaa");
        file.mkdirs();//mkdirs()用来创建多级目录
    }
}

Java文件IO操作_第8张图片

文件重命名使用 renameTo(File dest)方法,file. renameTo(File dest)表示把file文件重命名为dest文件。这里我们把IOTest重命名为IOTestDemo2:

package io;

import java.io.File;

public class IODemo3 {
    public static void main(String[] args) {
        File file=new File("./IOTest");
        File dest=new File("./IOTestDemo2");
        System.out.println(file.renameTo(dest));//修改成功返回true,修改失败返回false
    }
}

Java文件IO操作_第9张图片其他的方法这里就不过多展示了,可以自己实践一下。 

注意:new 出来的file对象只是一个对象,并不是文件的实体,需要我们自行去创建文件实体。创建文件时需要我们使用mkdir方法来创建,如果我们的文件已经存在,使用mkdir方法后不会出现创建该文件,也不会对原文件进行覆盖。 

Java对文件内容的操作(读和写)  

首先我们要对输入流和输出流有个宏观的认识:

输入输出流构成我们的IO.

Java文件IO操作_第10张图片

从硬盘读取数据到内存中的流,就是输入流-------------->FileInputStream

从内存中读取数据到硬盘中的流,就是输出流 ------------->FileOutputStream

所谓的输入输出都是相对于应用程序说的,朝向应用程序的是输入方向,远离应用程序的是输出发方向。

文件操作字节流 

FileInputStream(文件输入流)(读)继承自InputStream

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class IODemo2 {
    public static void main(String[] args) throws FileNotFoundException {
        //FileInputStream构造方法中字符串可以是绝对路径。也可以是相对路径,这里采用相对路径
        FileInputStream fileInputStream=new FileInputStream("TestDemo1");//文件如果不存在就会抛出FileNotFoundException
    }
}

Java文件IO操作_第11张图片

read方法 

read无参数 

read无参数版本一次读一个字节,返回类型为int,每次读取文件中一个字节,读取其ASCLL码的值,当所有数据读取完毕的时候,返回-1.(作为读取结束的标志)

import java.io.*;

public class IODemo3 {
    public static void main(String[] args) throws IOException {

        //字节流
        InputStream inputStream=new FileInputStream("test.txt");
        //进行读操作

        while (true){//一般读取文件的条件
           int b= inputStream.read();//b存放读取的ascll码
           if(b==-1){
               //读取完毕
               break;
           }
            //读取打印
            System.out.println(""+(byte)b);
        }


        inputStream.close();
    }
}

Java文件IO操作_第12张图片 

read有参数(byte数组)

这个版本的read和无参数read的区别在于这个是一次读取 一个数组长度的字节,并且将读取到的ascll存放到数组中,如果读取完毕所有的数组,同样放回-1,没有读取完的时候就是读取到了多少个字节就返回多少,需要注意的是,使用数组的时候,如果数组一轮读取被装满,下一轮读取的时候就会将数组中存放的数据进行覆盖,所以要及时使用数组中存放的数据。这个数组在这里也是起到了缓冲区的作用。

import java.io.*;

public class IODemo3 {
    public static void main(String[] args) throws IOException {

        //字节流
        InputStream inputStream=new FileInputStream("test.txt");
        //进行读操作
        while (true){
            byte[] buffer=new byte[1024];
            int len=inputStream.read(buffer);//输出型参数
            System.out.println("len = "+len);//一次读一个数组
            if(len==-1){
                //读取完毕

                break;
            }
            //读取的结果在buffer数组当中
            for (int i = 0; i 

Java文件IO操作_第13张图片 

read有参数版本的使用效率要比无参数版本要高,因为有参数版本使用数组,一次读取一个数组长度的数据,而无参数版本则一次读取一个字节,这样,同一套数据算下来,无参数read的io操作次数就会比较多,而read数组版本就io操作的次数就会相对减少很多,所以有参数版本可以有效的提高我们的io的一个效率。

FileOutputStream(文件输出流) (写)继承自OutputStream

这个是文件专门把数据从内存中写到我们的硬盘上的一个操作。

也是需要在构造方法中指明我们需要操作的文件。

        OutputStream outputStream=new FileOutputStream("test.txt");

需要注意的是,使用构造方法时的文件,如果是目录下不存在的,就会自动创建出该文件。

所以要确保目录下的文件是存在的,再进行使用。

write方法 

和FileInputStream一样,这个方法也是存在多种版本的:

Java文件IO操作_第14张图片

 只不过这里是写(输出),FileInputStream那里是读(输入)。

使用write需要注意的是,如果write之前,文件中已经存在数据了,那么使用write会清空原有的数据再进行写操作。

close方法 

close方法就是用来关闭当前的“流”所使用的。

那么为什么要进行关闭“流”的操作?主要是进程的一个关系。我们都知道进程中有个非常重要的东西,那就是文件描述符表,这个东西记录了进程打开了哪些文件。在一个进程当中,所有的线程共用一个文件描述符表,而文件描述符表就类似数组一样,它的大小是及其有限的,一旦装满就会出现问题,当装满后就无法进行文件的打开了,所以我们需要进行一个释放,而close方法就是对该表项的一个释放操作。

也有人会说这个可以解除JVM的GC进行回收,但是GC的回收是不准确的,你不知道他什么时候进行回收,很有可能你打开了很多文件后,文件描述符表已经满了,GC还没有来得及回收的情况。所以我们需要手动进行close操作。 

优雅的close写法 

close放到finally中 

把close操作放到finally中进行。


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class IODemo5 {
    public static void main(String[] args) throws IOException {
       FileOutputStream fileOutputStream=null;
        try {
            fileOutputStream=new FileOutputStream("test.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        finally {
            fileOutputStream.close();
        }
    }
}
Java中更优雅的写法:(将对象写在try的括号里面)

import java.io.FileOutputStream;
import java.io.IOException;

public class IODemo6 {
    public static void main(String[] args) throws IOException, InterruptedException {
        try ( FileOutputStream fileOutputStream=new FileOutputStream("test.txt")){
            fileOutputStream.wait(99);
        }//这样写会进行自动释放
    }
}

注意不是所有的对象都可以,一定要实现Closeable接口的才可以这样操作。 

Java文件IO操作_第15张图片 

文件操作字符流 

上述的FileInputStream和FileOutputStream都是字节流的,这里再介绍字符流的操作

FileReader(输入)读 继承自 Reader

FileReader是以字符为单位进行读取的。

FileReader fileReader=new FileReader("test.txt");

 read方法和字节流的差不多,只是这里是以字符为单位读取的。Java文件IO操作_第16张图片

import java.io.FileReader;
import java.io.IOException;

public class IODemo7 {
    public static void main(String[] args) throws IOException {
        FileReader fileReader=new FileReader("test.txt");
        while (true){
            int b=fileReader.read();
            if(b==-1){
                break;
            }
            System.out.println("读取的值为:"+(char) b);

        }
    }
}

Java文件IO操作_第17张图片  

FileWriter(输出)写 继承自 Writer 

FileWriter是以字符为单位进行输出的(写) 

其中的write方法和字节流的也差不多

Java文件IO操作_第18张图片

需要注意的是这里的write,如果参数是数字,写入到文件中就会写入对应数字ascll的字符。,如果是单引号中的字符,就直接写入单引号中的字符。

使用完write方法后需要使用一个flush方法,因为使用write方法后相当于把数据写入到缓冲区当中了,没有真正的写到硬盘,此时调用flush方法确保数据写入到硬盘之中。 

你可能感兴趣的:(JavaEE,java,开发语言)