【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第1张图片

目录

1. File 概述

1.1 File的属性

1.2 File的构造方法

1.3 File的方法

2.读文件

2.1 InputStream 概述

2.2 FileInputStream 概述

2.3 正确打开和关闭文件的方式

2.4 不同方式读取文件代码示例

2.4 另一种方法:利用 Scanner 进行字符读取

3.写文件

3.1 OutputStream 概述

3.2 利用 OutputStreamWriter 进行字符写入

4. 读文件和写文件的其他方式: Reader 和 Writer 

4.1 Reader 读取文件

4.2 Writer 写文件


1. File 概述

Java 中通过 java.io.File 类来对⼀个文件(包括目录)进行抽象的描述。注意,有 File 对象, 并不代表真实存在该文件

我们先来看看 File 类中的常见属性、构造方法和方法:

1.1 File的属性

修饰符及类型 属性 说明
static String pathSeparator 依赖于系统的路径分隔符,String 类型的表示
static char pathSeparator 依赖于系统的路径分隔符,char 类 型的表示

1.2 File的构造方法

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

其中 File(String pathname) 使用的最多,下面是使用实例:

File f1 = new File("C:/Users/1/test.txt");
File f2 = new File("./test.txt");

1.3 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() 判断用户是否对文件有可写权限

使用示例

getParent(),getName(),getPath(),getAbsolutePath(),getCanonicalPath()

public static void main(String[] args) throws IOException {
        File f = new File("C:/Users/1/test.txt");
        //File f = new File("./test.txt");
        System.out.println(f.getParent());
        System.out.println(f.getName());
        System.out.println(f.getPath());
        System.out.println(f.getAbsolutePath());
        System.out.println(f.getCanonicalPath());
    }

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第2张图片

exists(),isDirectory(),isFile(),createNewFile()

createNewFile(): 根据 File 对象,自动创建⼀个空文件。成功创建后返回 true

public static void main(String[] args) throws IOException {
        File file = new File("./test.txt");
        System.out.println(file.exists());
        System.out.println(file.isFile());
        System.out.println(file.isDirectory());

        boolean ret = file.createNewFile();
        System.out.println("ret = " + ret);

        System.out.println(file.exists());
        System.out.println(file.isFile());
        System.out.println(file.isDirectory());
    }

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第3张图片

 

delete(),deleteOnExit()

delete():根据 File 对象,删除该文件。成功删除后返回 true

public static void main(String[] args) throws InterruptedException {
        File file = new File("./test.txt");
        boolean ret = file.delete();
        System.out.println("ret = " + ret);
    }

deleteOnExit():根据 File 对象,标注文件将被删除,删除动作会到 JVM 运⾏结束时才会进行

public static void main(String[] args) throws InterruptedException {
        File file = new File("./test.txt");      
        //等程序结束后再删除文件
        file.deleteOnExit();
        Thread.sleep(3000);
    }

list(),listFiles()

list():返回 File 对象代表的目录下的所有文件名

public static void main(String[] args) {
        File file = new File(".");
        String[] files = file.list();
        System.out.println(Arrays.toString(files));
    }

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第4张图片

listFiles():返回 File 对象代表的目录下的所有件,以 File 对象表⽰

public static void main(String[] args) {
        File file = new File(".");
        File[] files = file.listFiles();
        System.out.println(Arrays.toString(files));
    }

mkdir():创建 File 对象代表的目录

public static void main(String[] args) {
        File f = new File("./aaa");
        //需要在构造方法中把路径创建好,再通过mkdir来创建
        boolean ret = f.mkdir();
        //boolean ret = f.mkdirs(); //创建多级目录
        System.out.println(ret);
    }

mkdirs():创建 File 对象代表的目录,如果必要,会创建中间目

public static void main(String[] args) {
        File f = new File("./aaa/bbb/ccc");
        //需要在构造方法中把路径创建好,再通过mkdir来创建
        boolean ret = f.mkdirs(); //创建多级目录
        System.out.println(ret);
    }

renameTo(File dest):进行文件改名,也可以视为我们平时的剪切、粘贴操作

修改文件名:

public static void main(String[] args) {
        File src = new File("./test.txt");
        File dest = new File("./test2.txt");
        boolean ret = src.renameTo(dest);//重命名和移动目录
        System.out.println(ret);
    }

修改路径:

public static void main(String[] args) {
        File src = new File("./test2.txt");
        File dest = new File("./aaa/test2.txt");
        boolean ret = src.renameTo(dest);//重命名和移动目录
        System.out.println(ret);
    }

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第5张图片

2.读文件

2.1 InputStream 概述

方法

修饰符及返回值类型 方法签名 说明
int read() 读取⼀个字节的数据,返回 -1 代表已经完全读完了
int read(byte[] b) 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表已经读完了
int read(byte[] b, int off, int len) 最多读取 len - off 字节的数据到 b 中,从 off 开始,返回实际读到的数量;-1 代表已经读完了
void close() 关闭字节流

byte[] b 是一个输出型参数, 会将文件的内容读取到b数组中,单位是字节. 

说明

InputStream 只是⼀个抽象类,要使⽤还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应⼀个 InputStream 类,我们现在只关心从文件中读取,所以使用 FileInputStream

2.2 FileInputStream 概述

构造方法

签名 说明
FileInputStream(File file) 利⽤ File 构造文件输⼊流
FileInputStream(String name) 利⽤文件路径构造文件输⼊流

2.3 正确打开和关闭文件的方式

不建议使用下面这种方式来关闭文件:

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第6张图片

因为在文件操作的执行过程中, 程序可能会在中途退出, 如遇到 return, 或者抛出异常未正确处理等, 会导致文件无法正常关闭, 造成文件资源泄露.

文件资源泄露:在java PCB中有文件描述符表, 记录了当前进程都打开了哪些文件, 每次打开一个文件, 都是需要在文件描述符表中占据一个位置, 如果不关闭还一直打开其他文件, 就会导致文件描述符表被耗尽(文件描述符表长度有上限). 当文件描述符表被耗尽后, 后续再打开文件就会打开失败, 就会一起后续一系列的逻辑出现问题.

下面是建议使用的文件关闭方法:

1.使用finally

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第7张图片

在javaSE中提到过finally的一个知识点:

        try {
            // 可能会发生异常的代码
        } catch (Exception e) {
            // 异常处理
        } finally {
            // 无论是否发生异常,都会执行的代码
        }

2. 使用java中提供的"try-with-resources"语句

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第8张图片

Java中提供了"try-with-resources"语句,用于自动关闭实现了"AutoCloseable"接口的资源,无需显式调用close()方法来关闭资源。这个语句可以在代码块结束后自动关闭资源,无论代码块是正常执行完毕还是发生了异常。

 

2.4 不同方式读取文件代码示例

1.每次读取一个字节, 以16进制输出:

public static void main(String[] args) throws IOException{
        try(InputStream inputStream = new FileInputStream("./test.txt")) {
            //进行文件操作
            while(true) {
                int n = inputStream.read();
                if(n == -1) {
                    //文件读取完毕
                    break;
                }
                //打印这个字节的数据
                System.out.printf("%x ",n);
            }
        }
    }

 

2.一次读取若干个字节,以String字符串的形式输出:

public static void main(String[] args) throws IOException{
        try(InputStream inputStream = new FileInputStream("./test.txt")) {
            //进行文件操作
            while(true) {
                byte[] buffer = new byte[1024];
                int n = inputStream.read(buffer);
                if(n == -1) {
                    //文件读取完毕
                    break;
                }
                //打印这个字节的数据
                String s = new String(buffer,0,n);
                System.out.print(s);
            }
        }
    }

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第9张图片

2.4 另一种方法:利用 Scanner 进行字符读取

上述例子中,我们看到了对字符类型直接使用 InputStream 进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该工作,就是 Scanner 类。

public static void main(String[] args) {
        try(InputStream inputStream = new FileInputStream(",/test.txt")) {
            Scanner scanner = new Scanner(inputStream);
            while(scanner.hasNext()) {
                String s = scanner.next();
                System.out.println(s);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

3.写文件

3.1 OutputStream 概述

方法

返回值类型

⽅法签名 说明
void write(int b) 写入一个字节的数据
void write(byte[] b) 将 b 这个字符数组中的数据全部写入 os 中
int write(byte[] b, int off, int len) 将 b 这个字符数组中从 off 开始的数据写入 os 中,⼀共写 len 个
void close() 关闭字节流
void flush() 见下面

flush()重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的⼀个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域⼀般称为缓冲区。但造成⼀个结果,就是我们写的数据,很可能会遗留⼀部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中.

说明

OutputStream 同样只是⼀个抽象类,要使⽤还需要具体的实现类。我们现在还是只关心写入文件 中,所以使⽤ FileOutputStream

3.2 利用 OutputStreamWriter 进行字符写入

public static void main(String[] args) {
        //使用OutPutStream来写文件
        try(OutputStream outputStream = new FileOutputStream("./test.txt")) {
            byte[] buffer = new byte[]{97,98,99,100,101,102};
            outputStream.write(buffer);
            // 不要忘记 flush
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } ;
    }

 文件中得到的结果:

注意: 

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第10张图片

如果要以追加的形式写文件,需要在FileOutputStream的构造方法中加true参数:

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第11张图片

写入英文字符串

public static void main(String[] args) {
        //使用OutPutStream来写文件
        try(OutputStream outputStream = new FileOutputStream("./test.txt")) {
            String s = "Nothing";
            byte[] buffer = s.getBytes();
            outputStream.write(buffer);
            // 不要忘记 flush
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } 
    }

写入中文字符串

public static void main(String[] args) {
        //使用OutPutStream来写文件
        try(OutputStream outputStream = new FileOutputStream("./test.txt")) {
            String s = "你好中国";
            byte[] buffer = s.getBytes("utf-8");
            outputStream.write(buffer);
            // 不要忘记 flush
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

4. 读文件和写文件的其他方式: Reader 和 Writer 

Reader 和 Writer 的使用方式和 InputStream,OutputStream 类似, 具体使用方式可以参考这两个

4.1 Reader 读取文件

方法

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第12张图片

使用示例:  

public static void main(String[] args) {
        //使用字符流读取文件内容
        try(Reader reader = new FileReader("./test.txt")) {
            while(true) {
                char[] buffer = new char[1024];
                int n = reader.read(buffer);
                if(n == -1) {
                    break;
                }
                String s = new String(buffer,0,n);
                System.out.println(s);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第13张图片

4.2 Writer 写文件

方法 

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第14张图片

使用示例: 

public static void main(String[] args) {
        try(Writer writer = new FileWriter("./test.txt")) {
            String s = "你好";
            writer.write(s);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

 如果要以追加的形式写文件, 只需要在在构造方法中加一个true即可:

Writer writer = new FileWriter("./test.txt",true)

【JavaEE】文件操作: File 类的用法和 InputStream, OutputStream 的用法_第15张图片

你可能感兴趣的:(JavaEE,java-ee,java)