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

发布时间:2024年01月18日

目录

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 StringpathSeparator依赖于系统的路径分隔符,String 类型的表示
static charpathSeparator依赖于系统的路径分隔符,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的方法

修饰符及返回值类型方法签名说明
StringgetParent()返回 File 对象的父目录文件路径
StringgetName()返回 FIle 对象的纯文件名称
StringgetPath()返回 File 对象的文件路径
StringgetAbsolutePath()返回 File 对象的绝对路径
StringgetCanonicalPath()返回 File 对象的修饰过的绝对路径
booleanexists()判断 File 对象描述的文件是否真实存在
booleanisDirectory()判断 File 对象代表的文件是否是?个目录
booleanisFile()判断 File 对象代表的文件是否是?个普通文件
booleancreateNewFile()根据 File 对象,?动创建?个空文 件。成功创建后返回 true
booleandelete()根据 File 对象,删除该文件。成功 删除后返回 true
voiddeleteOnExit()根据 File 对象,标注文件将被删 除,删除动作会到 JVM 运行结束时 才会进行
String[]list()返回 File 对象代表的目录下的所有文件名
File[]listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象表示
booleanmkdir()创建 File 对象代表的目录
booleanmkdirs()创建 File 对象代表的目录,如果必 要,会创建中间目录
booleanrenameTo(File dest)进行文件改名,也可以视为我们平时的剪切、粘贴操作
booleancanRead()判断用户是否对文件有可读权限
booleancanWrite()判断用户是否对文件有可写权限

使用示例

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());
    }

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());
    }

?

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));
    }

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);
    }

2.读文件

2.1 InputStream 概述

方法

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

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

说明

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

2.2 FileInputStream 概述

构造方法

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

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

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

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

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

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

1.使用finally

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

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

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

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);
            }
        }
    }

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 概述

方法

返回值类型

?法签名说明
voidwrite(int b)写入一个字节的数据
voidwrite(byte[] b)将 b 这个字符数组中的数据全部写入 os 中
intwrite(byte[] b, int off, int len)将 b 这个字符数组中从 off 开始的数据写入 os 中,?共写 len 个
voidclose()关闭字节流
voidflush()见下面

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);
        } ;
    }

?文件中得到的结果:

注意:?

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

写入英文字符串

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 读取文件

方法

使用示例:??

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);
        }
    }



4.2 Writer 写文件

方法?

使用示例:?

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)

文章来源:https://blog.csdn.net/m0_73648729/article/details/135636210
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。