文件操作IO-2

目录

操作文件的方法

重点方法

构造方法

对于文件树结构的修改方法

创建新文件方法

创建目录

删除文件方法

移动节点(重命名) 

判断文件属性

判断是否存在方法

判断文件存在&&是文件夹

判断文件存在&&是普通文件

获取文件标准路径

返回文件的一般绝对路径 

返回文件的标准绝对路径

针对目录

 对此路径进行遍历

获取文件名方法

得到文件名(当前文件名,没有路径其他信息)

得到父类文件名

得到该文件最后一次修改的时间

得到文件的所有孩子

相对路径

进程运行时的工作目录在哪?

关于内容的读写内容的读写——关于读的内容

读文件用到的类和模型

1.输入流

2.使用具体类

3.关于抽象模型

4.记得关闭

具体方法

关闭信号

使用byte数组的输入方式 —— read(byte[] b)

直接接收——read() 方法

利用InputStream进行二进制数据的直接读取方式

String的构造方法(不推荐)

 利用Scanner方法

关于内容的读写内容的读写——关于写的内容

缓冲区 —> 平衡写入速度

缓冲区刷盘

OutputStreamWriter

PrintWriter

操作文件的方法

重点方法

构造方法

可以用绝对路径和相对路径,但我一般用绝对路径。

File file = new File("C:\\Users\\DELL\\Desktop\\exercise");

对于文件树结构的修改方法

创建新文件方法

file.createNewFile();

创建目录

会创建该路径下所有不存在的目录

file.mkdirs();

删除文件方法

file.delete();

移动节点(重命名) 

        File file = new File("D:\\课程\\2022-06-29-2022火箭班-IO\\src\\nihao.txt");
        File dest = new File("D:\\课程\\2022-06-29-2022火箭班-IO\\src\\bye.txt");
        //该目录会实现剪切效果,会将原本目录下的文件移动到新目录下
        //File dest = new File("D:\\课程\\2022-06-29-2022火箭班-IO\\dest\\nihao.txt");
        file.renameTo(dest);

判断文件属性

判断是否存在方法

file.exists()

判断文件存在&&是文件夹

file.isDirectory();

判断文件存在&&是普通文件 

file.isFile();

获取文件标准路径

返回文件的一般绝对路径 

String absolutePath = file.getAbsolutePath();

 返回文件的标准绝对路径

String canonicalPath = file.getCanonicalPath();

 针对目录

file.listFiles();

 对此路径进行遍历

一般用于目录文件夹的整体删除

在此只列出深度遍历,广度遍历则需要借助队列进行。

    private static void traversalDepthFirst(File dir) throws Exception {
        // 1. 找到这个目录下的所有孩子
        File[] files = dir.listFiles();
        if (files == null) {
            return;
        }
 
        // 2. 针对每个孩子,判断是目录还是文件
        for (File file : files) {
            if (file.isDirectory()) {
                // 如果确定是个目录,则继续递归去遍历处理
                System.out.println("[D] " + file.getCanonicalPath());
                traversalDepthFirst(file);
            } else {
                System.out.println("[F] " + file.getCanonicalPath());
            }
        }
    }

 

获取文件名方法

得到文件名(当前文件名,没有路径其他信息)

 

file.getName();

 得到父类文件名

//得到父类文件名
file.getParent();
//想得到标准写法,需要先得到父类文件,再获取标准绝对路径。
String ret = file.getParentFile().getCanonicalPath();

得到该文件最后一次修改的时间

file.lastModified();

 得到文件的所有孩子

File[] files = file.listFiles();

 

相对路径

关于相对路径,需要明确

进程运行时的工作目录在哪?

工作目录:current working diretory(cwd)

在JVM下通常就是进程启动时的目录。

也就是说你的idea文件夹放哪哪就是启动目录

关于内容的读写内容的读写——关于读的内容

读的方式有两种:

1).直接读取(以二进制数据的方式读取,表现在代码中byte为单位);

2).文本读取

读文件用到的类和模型
1.输入流
在读文件时,我们用java.io.InputStream作为输入流来进行输入。

2.使用具体类
InputStream本身是抽象类,我们用子类FileInputStream进行文件输入。

3.关于抽象模型
输入的过程是可以通过模型表示的,我们可以我们建立的输入流看作是水龙头,而我们需要输入的文件当作是一个水塔,最后,我们还需要一个水桶来接住水塔流过水龙头再流下来的水

水塔:具体文件

水龙头:FileInputStream类

水桶:byte[] 数组

4.记得关闭

记得用完之后把水龙头关闭

具体方法

我们使用FileInputStream类的read()方法来承载输入流

关闭信号

我们在代码中用 -1 来表示EOS(关闭信号)

使用byte数组的输入方式 —— read(byte[] b)

此方法会返回接了多少水。

这个方法一次可以接很多的水,我们只需要在水桶接完水后,再拿一个恰好可以装这些水的容器把水装好,然后进行这个容器的遍历即可。

public static void main(String[] args) throws Exception {
        InputStream is = new FileInputStream("./hello.txt");
        // FileInputStream 可以赋值给 InputStream,是因为 有继承关系 && FileInputStream 是 InputStream 的下级类
 
        // 准备好一个水桶
        byte[] buf = new byte[1024];        // 1024 代表能接 1024 滴(字节)水,我们准备好桶的容量
 
        // 拿着准备好的桶去水龙头接水
        int n = is.read(buf);
        // 这里的 n 代表这次真正接到了多少滴(字节)水
        // n 一定小于等于 1024 && n >= 0
//        System.out.println(n);  // 28
        // 真正的数据放在 buf 从 [0, 28)
        byte[] bytes = Arrays.copyOf(buf, n);
        for (byte b : bytes) {
            System.out.printf("%02x\n", b);
        }
 
        is.close();
    }

 直接接收——read() 方法

这个方法在水龙头流过每一滴水的时候直接接住,不用水桶和容器,没有水流了返回的int值会变为-1,这个时候就要退出接水过程然后关闭水龙头了。

public static void main(String[] args) throws Exception {
        InputStream is = new FileInputStream("./hello.txt");
        while (true) {
            int data = is.read();
            if (data == -1) {
                // 所有数据都被读完了
                break;
            }
 
            // 否则,data 就是我们取到的数据
            byte b = (byte) data;
            System.out.printf("%02x\n", b);
        }
        is.close();
    }

 

利用InputStream进行二进制数据的直接读取方式

String的构造方法(不推荐)

可以采用String的构造方法就可以将byte[]数组直接转换为文本文件里的文本。

落实到代码上,就不需要再进行byte数组的遍历了,而是直接把byte数组传进去就可以

try (InputStream is = new FileInputStream("./hello.txt")) {
            byte[] buf = new byte[1024];
            int n = is.read(buf);
//            System.out.println(n);
//            for (int i = 0; i < n; i++) {
//                System.out.printf("%02x ", buf[i]);
//            }
            String s = new String(buf, 0, n, "UTF-8");
            System.out.println(s);
        }

 

 利用Scanner方法

我们可以利用Scanner方法,直接将Scanner比作水桶,输入流直接进入Scanner即可

Scanner其实也需要close,所以也加一个try 只是平时我们没有关而已。

try (InputStream is = new FileInputStream("./hello.txt")) {
            try (Scanner scanner = new Scanner(is, "UTF-8")) {
                while (scanner.hasNextLine()) {
                    String line = scanner.nextLine();   // 默认去掉了换行符
                    System.out.println("|" + line + "|");
                }
            }
        }

 

关于内容的读写内容的读写——关于写的内容
缓冲区 —> 平衡写入速度
写内容实际上是通过数据经过内存到硬盘的,而因为内存的写速度远远快于硬盘的写速度,

我们就需要一个“缓冲区 buffer”来平衡速度之差。

缓冲区刷盘
缓冲区的刷盘就是将缓冲区的数据冲刷到硬盘里。以下几种情况会发生刷盘现象:

1.缓冲区满了或者达到一定阈值。

2.达成间隔时间

3.进程主动刷盘

在关闭之前

仍会有一部分数据留在内存中,这时候就要经过一次冲盘将数据全部冲到硬盘中去。

在使用OutputStreamWriter实现类时,要注意最后用.flush()来将缓冲区的数据刷盘。

OutputStreamWriter
我们采用Writer的子类OutputStreamWriter来完成写操作。

这一步是为了做字符集编码处理
 

public static void main1(String[] args) throws Exception {
        try (OutputStream os = new FileOutputStream("./world.txt")) {
            try (Writer writer = new OutputStreamWriter(os, "UTF-8")) {
                writer.write("你好中国\r\n");
                writer.write("没什么");
                writer.flush();
            }
        }
    }

 

PrintWriter

配合PrintWriter,并且在其构造方法传入writer对象可以达成类似于print方法的效果。

public static void main(String[] args) throws Exception {
        try (OutputStream os = new FileOutputStream("./world.txt")) {
            try (Writer writer = new OutputStreamWriter(os, "UTF-8")) {
                try (PrintWriter printWriter = new PrintWriter(writer)) {
                    printWriter.println(1 + 1);
                    printWriter.print(3);
                    printWriter.printf("%s + %d", "我", 3);
 
                    printWriter.flush();
                }
            }
        }
    }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值