文件操作及面试题

目录

文本文件和二进制文件

File概述

递归去查看某个目录下的所有文件与目录

InputStream概述

OutputStream 概述

文件操作的应用

面试题:递归文件路径并且删除指定文件

将一个指定路径的文件复制到另一个文件中去


1.文件

此处的文件有多种含义,不仅仅包括硬盘上的文件以及保存文件的目录,还包括许多的硬件设备,软件资源。

2.硬盘

硬盘与内存对比:

1.硬盘的储存空间大大,内存的储存空间小

2.硬盘的速度慢,内存的速度块

3.硬盘的成本低,内存的成本高

4.硬盘能够持久化储存,内存断电后数据消失。

3.文件系统

文件系统上的目录结构是一个树形结构,是N叉树。

4.文件路径

在文件系统中如何定位我们的一个唯一的文件是重要的难题。从文件的分布的树形结构来看,每个节点都可以从一条跟开始,一直到节点所在的路径来描述。这就是绝对路径

除了从根节点开始进行路径的描述,也可以从任意节点出发,进行路径的描述,这种描述路径的方式就是相对路径,相对于当前所在节点的一条路径。


文本文件和二进制文件

文本文件:当前文件里储存的所有内容都是”文本“都是合法的字符,这些字符的编码方式按照字符集。虽然叫做文本文件但是内部还是二进制,只不过这些二进制有据可查。文本文件底层虽然是二进制储存,但是java在把文本文件读取出来的时候会自动查询码表,把二进制转化成一个个字符。而二进制文件则没有上述转换过程。

二进制文件:顾名思义就是里面储存二进制的文件。一般这种文件不能被直接打开,而是要通过特定的应用程序打开。


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()判断⽤⼾是否对⽂件有可写权限

说明一下,上述方法有的在使用的时候要声明一下IOException异常

1.因为有可能在使用文件的时候硬盘空间会不够用。

2没有权限,确保有权限操作文件的时候才能进行程序。读权限/写权限等待

通过renameTo(File dest)可以实现文件的转移。


递归去查看某个目录下的所有文件与目录


文件内容的读写——数据流

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

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

FileInputStream概述

签名说明
FileInputStream(File file)利⽤ File 构造⽂件输⼊流
FileInputStream(String name)利⽤⽂件路径(绝对/相对路径)构造⽂件输⼊流

此处隐含了一个打开文件,针对文件的读写必须先打开文件。

既然打开文件,那么就要关闭文件。打开文件其实就是打开进程的文件描述符表中,在里面创建一个新的项目。

文件描述符表可以认为是一个数组,描述了进程打开了哪些文件。每打开一项进程描述符表就多处一项信息,但是这个数组的长度是固定,如果打开文件后不及时主动关闭,一直打开不去关闭,,这里的资源就会越来越少,最后数组的空间满了就会打开失败。不及时释放就会造成内存泄漏。

为了防止忘记colse,就可以把InputStream放入try语句中,每次try执行完就会自动调用colse。

因为InputStream继承了Closeable接口,


OutputStream 概述

⽅法

修饰符及返回值类型⽅法签名说明
voidwrite(int b)写⼊要给字节的数据
voidwrite(byte[] b)将 b 这个字符数组中的数据全部写⼊ os 
intwrite(byte[] b, int off, int len)将 b 这个字符数组中从 off 开始的数据写⼊ os 中,⼀共写 len 个
voidclose()关闭字节流
voidflush()重要:我们知道 I/O 的速度是很慢的,所以,⼤多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写⼊内存的⼀个指定区域⾥,直到该区域满了或者其他指定条件时才真正将数据写⼊设备中,这个区域⼀般称为缓冲区。但造成⼀个结果,就是我们写的数据,很可能会遗留⼀部分在缓冲区中。需要在最后或者合适的位置,调⽤ flush(刷新)操作,将数据刷到设备中。

说明

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


InputStresm 和 OutputStream 是用于读写字节流的,读写数据的基本单位是字节。

Reader 和 Writer 用于读写字符流的,读数据的基本单位是字符。字符流内部做的工作会更多一些,读取到的字符会自动查询码表,把二进制数据转换成字符。

但是是以Rean/Write结尾的就是实现了Read/Write对象,以InputStream/OutStream结尾的就是实现了InputStream/OutputStream的字节流对象。

什么是输入输出?

以cpu的视角来看,数据远离cou就是输出,数据靠近cpu就是输入。


文件操作的应用

1.两中不同的方式读文件

使用InputStream读取文本,一次读取一个字节

一次读取多个字节


使用OutputStream输入字节,一个出入多个


使用Reader读取字符

使用Reader读取多个字符存放在数组里


使用Write写入


利⽤ Scanner 进⾏字符读取

上述例⼦中,我们看到了对字符类型直接使⽤ InputStream 进⾏读取是⾮常⿇烦且困难的,所以,我们使⽤⼀种我们之前⽐较熟悉的类来完成该⼯作,就是 Scanner 类。

构造⽅法说明
Scanner(InputStream is, String charset)使⽤ charset 字符集进⾏ is 的扫描读取


面试题:递归文件路径并且删除指定文件
private static void scan(File srcFilePath,String nameFile){
        if(!srcFilePath.isDirectory()){
            return;
        }
        File[] files = srcFilePath.listFiles();
        if(files == null || files.length == 0){
            return;
        }
        for (File f:files) {
            if(f.isFile()){
                //是否删除文件
                doDelete(f,nameFile);
            }
            else scan(f,nameFile);
        }
    }

    private static void doDelete(File file,String nameFile){
       if(!file.getName().contains(nameFile)){
           return;
       }
       Scanner scanner = new Scanner(System.in);
        System.out.println("是否删除文件? Y/N");
        String answer = scanner.nextLine();
        if(answer.equals("Y") || answer.equals("y")){
            file.delete();
            System.out.println("删除成功");
        }
    }

    public static void main(String[] args) {
        System.out.println("请输入源路径");
        Scanner scanner  = new Scanner(System.in);
        String srcFilePath = scanner.nextLine();
        File srcfilePath = new File(srcFilePath);
        if(!srcfilePath.isDirectory()){
            System.out.println("输入路径错误");
            return;
        }
        System.out.println("请输入文件名称");
        String nameFile = scanner.nextLine();
        File  srcFile = new File(nameFile);
        scan(srcfilePath,nameFile);
    }

将一个指定路径的文件复制到另一个文件中去
 //将一个文件复制到另一个文件中去
    public static void main(String[] args) {
        System.out.println("输入源文件路径");
        Scanner scanner = new Scanner(System.in);
        String srcFilePath = scanner.nextLine();
        File srcfile = new File(srcFilePath);
        if(!srcfile.isFile()){
            System.out.println("源文件路径有误");
            return;
        }

        System.out.println("输入目标文件路径");
        String destFilePath = scanner.nextLine();
        File destfile = new File(destFilePath);
        if(!destfile.isFile()){
            System.out.println("目标文件路径有误");
            return;
        }

        try (InputStream inputStream = new FileInputStream(srcfile);
             OutputStream outputStream = new FileOutputStream(destfile)){

            while (true){
                byte[] buffer = new byte[1024];
                int n = inputStream.read(buffer);
                if(n == -1) return;
                outputStream.write(buffer,0,n);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值