文件操作 IO

news2024/12/21 19:04:02

文件(File)

狭义的文件: 指的是硬盘上的文件和目录
广义的文件: 泛指计算机中很多软硬件资源(操作系统中把很多硬件和软件资源抽象成了文件, 按照文件的方式同意管理)

本章内容只讨论狭义的文件

路径

  1. 绝对路径: 以c: , d: 盘符开头的路径
  2. 相对路径: 以当前所在的目录为基准(工作目录), 以. 或 … 开头(有时 . 可以省略), 找到指定的路径

那么我们的IDEA的工作路径在哪呢?
IDEA 的工作路径默认就是在当前的项目所在目录
在这里插入图片描述

Java 对于文件的操作

  1. 针对文件系统操作(文件的创建, 删除, 重命名)
  2. 针对文件内容的操作(文件的读和写)

Java 标准库中提供了File这个类

在这里插入图片描述
parent 表示当前文件所在目录
child 表示自身的文件名

        File file = new File("d:/text.txt");

构建一个File 对象

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

public class IODemo1 {
    public static void main(String[] args) throws IOException {
        File file = new File("./test1.txt");
        // 获取文件名
        System.out.println(file.getName());

        // 获取父级路径
        System.out.println(file.getParent());

        // 获取完整路径
        System.out.println(file.getPath());

        // 获取绝对路径
        System.out.println(file.getAbsoluteFile());

        // 获取绝对路径的简化路径
        System.out.println(file.getCanonicalPath());
    }
}

判断文件

import java.io.File;

public class IODemo2 {
   public static void main(String[] args) {
       File file = new File("d:/f1/f2/test1.txt");
       // 这个文件是否存在
       System.out.println(file.exists());

       // 这是不是一个文件
       System.out.println(file.isFile());

       // 这是一个目录吗
       System.out.println(file.isDirectory());
   }
}

创建文件

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

public class ThreadDemo3 {
    public static void main(String[] args) throws IOException {
        File file = new File("./test.txt");
        //创建这个文件
        file.createNewFile();
    }
}

在这里插入图片描述
删除文件

import java.io.File;

public class IODemo4 {
    public static void main(String[] args) {
        File file = new File("./test.txt");
        // 删除文件
        file.delete();
    }
}

deleteOnExit


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

public class IODemo5 {
    public static void main(String[] args) throws IOException {
        File file = new File("test.txt");
        System.out.println(file.exists());
        System.out.println(file.createNewFile());
        System.out.println(file.exists());
        //程序运行结束后删除
        file.deleteOnExit();
        System.out.println(file.exists());
    }
}

目录的创建

import java.io.File;

public class IODemo6 {
    public static void main(String[] args) {
        File dir = new File("d:/f1/f2/f3/f3");
        dir.mkdir();   // 只能创建一级目录
        dir.mkdirs();  // 创建多级目录
    }
}

文件的重命名

import java.io.File;

public class IODemo7 {
    public static void main(String[] args) {
        File file = new File("./aaa/bbb/test.txt");
        File file1 = new File("./aaa/bbb/test2.txt");
        file.renameTo(file1);
    }
}

Java 标准库的流对象

从类型上分成两个大类

  1. 字节流: 操作二进制数据的
  2. 字符流: 操作文本数据

在这里插入图片描述
read 无参数版本:一次只读一个字节
read 有一个参数版本: 把读到的内容填充到参数的这个字节数组中, (此处的参数是一个输出型参数), 返回值是实际读取的字节数
read 有三个参数的版本: 和一个参数的差不多. 只不过是往数组的一部分区间里尽可能填充

思考:

read 读取的是一个字节, 按理说应该返回一个 byte , 但是实际上是返回int, 这是为什么呢?
这里除了表示byte里的0~255 (-128 ~ 127) 这样的情况外, 还需要表示一个特殊情况, -1,这个标记表示读取文件结束了(读到末尾了).

UTF-8 每个汉字三个字节

字节流读取:

import java.io.*;

public class IODemo8 {
    // 使用字节流读取文件
    public static void main(String[] args) throws IOException {
        // 创建InputStream 对象的时候, 使用绝对路径或者相对路径都行, 也可以使用File对象
        InputStream inputStream = new FileInputStream("d:/test.txt");

//        //进行读操作
//        while (true) {
//            int b = inputStream.read();
//            if(b == -1) {
//                // 读取完毕
//                break;
//            }
//            //System.out.println(""+ (byte)b);
//            System.out.printf("%x",(byte)b);
//        }

            while (true) {
                byte[] buffer = new byte[1024];
                int len = inputStream.read(buffer);
                System.out.println("len: "+ len);
                if (len == -1) {
                    break;
                }
                // 此时读取的字符就被放到了byte[] 中了.
                for (int i = 0; i < len; i++) {
                    System.out.printf("%x\n", (byte)buffer[i]);
                }
            }

            inputStream.close();
    }
}

buffer 存在的意义,是为了提高 IO 操作的效率,
单次 IO 操作, 是要访问硬盘的, 所以就会比较耗费时间,
缩短了 IO 操作的次数, 所以效率也就提高了

字节流写文件
在这里插入图片描述
也是类似的三个方法

public class IODemo9 {
    // 进行写文件
    public static void main(String[] args) throws IOException {
        OutputStream outputStream = new FileOutputStream("d:/test.txt");
        outputStream.write(97);
        outputStream.write(98);
        outputStream.write(99);
        outputStream.write(100);
        outputStream.close();
    }
}

在这里插入图片描述
更推荐的写法
这个写法虽然没有显示的写 close , 但是在 try 语句执行完的时候, 会自动执行到 close

public class IODemo {
    public static void main(String[] args) throws IOException {
        try (OutputStream outputStream = new FileOutputStream("d:/test.txt")) {
            outputStream.write(97);
            outputStream.write(97);
            outputStream.write(97);
            outputStream.write(97);
            outputStream.write(97);
            outputStream.write(97);
        }
    }
}

字符流读文件

package io;

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

public class IODemo10 {
    // 字符流的操作
    public static void main(String[] args) {
        try (Reader reader = new FileReader("d:/test.txt")) {
            while (true) {
                int ch = reader.read();
                if (ch == -1) {
                    break;
                }
                System.out.println("" + (char)ch);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

字符流写文件

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class IODemo11 {
    // 字符流写文件
    public static void main(String[] args) {
        try (Writer writer = new FileWriter("d:/test.txt")) {
            writer.write("hello world");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

下面我们实现一个删除文件的小程序

import java.io.File;
import java.util.Scanner;

public class IODemo12 {
    private static Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {
        // 让用户输入一个指定搜索的目录
        System.out.println("请输入一个要搜索的路径: ");
        String basePath = scanner.next();

        // 针对用户输入进行简单判定,
        File root = new File(basePath);
        if (!root.isDirectory()) {
            // 路径不存在, 或者是一个普通文件, 此时无法进行搜索
            System.out.println("输入的路径有误");
            return;
        }

        System.out.println("请输入要删除的文件名: ");
        // 此处使用 next, 不用 next.Line
        String nameToDelete = scanner.next();

        // 针对指定路径进行扫描, 递归操作
        // 先从根目录出发(root)
        // 先看看这个目录是否有我们要删除的文件, 如果有就删除, 否则下一个
        // 如果是包含了一些目录, 那就进行递归

        scanDir(root,nameToDelete);
    }

    private static void scanDir(File root, String nameToDelete) {
        // 1. 先列出当前路径下包含和目录
        File[] files = root.listFiles();
        if (files == null) {
            // 当前目录没东西, 进行下一步递归
            return;
        }
        // 遍历当前列出的结果
        for (File f: files) {
            if (f.isDirectory()) {
                // 如果是目录就进一步递归
                scanDir(f,nameToDelete);
            } else {
                // 如果是文件就判断
                if (f.getName().contains(nameToDelete)) {
                    System.out.println("确认要删除 " + f.getName() + "吗?");
                String choice = scanner.next();
                   if (choice.equals("Y") || choice.equals("y")) {
                        f.delete();
                       System.out.println("删除成功");
                   } else {
                       System.out.println("删除取消");
                   }
                }
            }
        }
    }
}

文件的复制
就是把一个文件按照字节一次读取, 把结果写入另一个文件中

import java.io.*;
import java.util.Scanner;

// 文件的拷贝
public class IODemo13 {
    public static void main(String[] args) throws RuntimeException {
        // 输入两个路径 一个源 一个目标路径 (从哪里拷贝到哪)
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要拷贝哪个文件: ");
        String srePath = scanner.next();
        System.out.println("请输入要拷贝到哪个地方: ");
        String destPath = scanner.next();

        File srcFile = new File(srePath);
        if (!srcFile.isFile()) {
            System.out.println("您输入的源路径有误!");
            return;
        }
        File destFile = new File(destPath);
        if (destFile.isFile()) {
            // 如果已经存在不能拷贝
            System.out.println("您输入的目标路径有误: ");
            return;
        }

        // 进行拷贝操作
        try (InputStream inputStream = new FileInputStream(srcFile);
             OutputStream outputStream = new FileOutputStream(destFile)) {

            // 进行读文件操作
            while (true) {
                int b = inputStream.read();
                if (b == -1) {
                    break;
                }
                outputStream.write(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1121305.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【问题思考总结】如何求椭圆的切线?【过椭圆外一点】

问题 今天做2009年数一的真题&#xff0c;发现第17题求切线十分难顶&#xff0c;我用的方法是切线和椭圆方程联立&#xff0c;还有切线斜率和椭圆上一点和远点斜率相乘等于-1的方法。 思考 经过思考后&#xff0c;我认为之前的那个属于是高中方法&#xff08;还不完全是&…

Prometheus接入AlterManager配置邮件告警(基于K8S环境部署)

文章目录 一、配置AlterManager告警发送至邮箱二、Prometheus接入AlterManager配置三、部署PrometheusAlterManager(放到一个Pod中)四、测试告警 注意&#xff1a;请基于 PrometheusGrafana监控K8S集群(基于K8S环境部署)文章之上做本次实验。 一、配置AlterManager告警发送至邮…

手把手入门Node框架Egg.js

0.介绍 Egg.js 是一个面向企业级应用开发的 Node.js 框架&#xff0c;它建立在 Koa.js 之上&#xff0c;提供了一种更简单、灵活的开发方式。Egg.js 提供了一些默认约定和最佳实践&#xff0c;可以帮助开发者快速构建可靠、可扩展的应用程序。 基于 Koa.js&#xff1a;Egg.js …

spacy.load(“en_core_web_trf“)报错TypeError: issubclass() arg 1 must be a class

使用spacy时遇到的问题 写在最前面&#xff1a; 安装spacy和en_core_web_trf时需要保证二者版本一致 安装及查看对应spacy版本 安装 pip install spacy查看版本 import spacy spacy.__version__安装en_core_web_trf 直接安装&#xff08;如果可以的话&#xff09; pytho…

【论文阅读】以及部署BEVFusion: A Simple and Robust LiDAR-Camera Fusion Framework

BEVFusion: A Simple and Robust LiDAR-Camera Fusion Framework BEVFusion&#xff1a;一个简单而强大的LiDAR-相机融合框架 NeurIPS 2022 多模态传感器融合意味着信息互补、稳定&#xff0c;是自动驾驶感知的重要一环&#xff0c;本文注重工业落地&#xff0c;实际应用 融…

反转链表review

反转链表 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }* }*/ class …

Rust逆向学习 (2)

文章目录 Guess a number0x01. Guess a number .part 1line 1loopline 3~7match 0x02. Reverse for enum0x03. Reverse for Tuple0x04. Guess a number .part 20x05. 总结 在上一篇文章中&#xff0c;我们比较完美地完成了第一次Rust ELF的逆向工作&#xff0c;但第一次编写的R…

JVM(Java Virtual Machine)垃圾收集器篇

前言 本文参考《深入理解Java虚拟机》一书&#xff0c;本文主要介绍几个经典的垃圾收集器&#xff1a;Serial、ParNew、parallelScavenge、CMS、Serial Old、Parallel Old、G1 本系列其他文章链接&#xff1a; JVM&#xff08;Java Virtual Machine&#xff09;内存模型篇 JV…

2434: 【区赛】[慈溪2013]统计方格

题目描述 给出一张 n 行 m 列仅由黑白方格组成的黑白图片&#xff08;行从上到下 1 到 n 编号&#xff0c;列从左到右 1 到 m 编号&#xff09;。如下图是一张由 17 行 18 列方格构成的黑白图片&#xff0c;图片中的任意一个方格要么是白色&#xff0c;要么是黑色。 仔细观察这…

介绍Sigmoid函数的平移、平滑和翻转【基于Python可视化分析】

文章目录 简介Sigmoid函数Sigmoid函数曲线调控参数设置python可视化参考 简介 本篇博客介绍了具有S型曲线的Sigmoid函数&#xff0c;以及如何设置、调整Sigmoid函数的参数实现S曲线的平滑、平移和翻转操作。博客给出了Python代码示例&#xff0c;更加深刻形象。&#x1f606;&…

hdlbits系列verilog解答(两输入与门)-06

文章目录 wire线网类型介绍一、问题描述二、verilog源码三、仿真结果 wire线网类型介绍 wire线网类型是verilog的一种数据类型&#xff0c;它是一种单向的物理连线。它可以是输入也可以是输出&#xff0c;它与reg寄存器数据类型不同&#xff0c;它不能存储数据&#xff0c;只能…

数据结构与算法 | 第二章:线性表

本文参考网课为 数据结构与算法 1 第二章线性表&#xff0c;主讲人 张铭 、王腾蛟 、赵海燕 、宋国杰 、邹磊 、黄群。 本文使用IDE为 Clion&#xff0c;开发环境 C14。 更新&#xff1a;2023 / 10 / 22 数据结构与算法 | 第二章&#xff1a;线性表 线性表总览线性结构概念特…

大数据技术学习笔记(三)—— Hadoop 的运行模式

目录 1 本地模式2 伪分布式模式3 完全分布式模式3.1 准备3台客户机3.2 同步分发内容3.2.1 分发命令3.2.2 执行分发操作 3.3 集群配置3.3.1 集群部署规划3.3.2 配置文件说明3.3.3 修改配置文件3.3.4 分发配置信息 3.4 SSH无密登录配置3.4.1 配置ssh3.4.2 无密钥配置 3.5 单点启动…

人工智能(6):机器学习基础环境安装与使用

1 库的安装 整个机器学习基础阶段会用到Matplotlib、Numpy、Pandas等库&#xff0c;为了统一版本号在环境中使用&#xff0c;将所有的库及其版本放到了文件requirements.txt当中&#xff0c;然后统一安装 新建一个用于人工智能环境的虚拟环境 mkvirtualenv ai matplotlib3.8…

Mybatis应用场景之动态传参、两字段查询、用户存在性的判断

目录 一、动态传参 1、场景描述 2、实现过程 3、代码测试 二、两字段查询 1、场景描述 2、实现过程 3、代码测试 4、注意点 三、用户存在性的判断 1、场景描述 2、实现过程 3、代码测试 一、动态传参 1、场景描述 在进行数据库查询的时候&#xff0c;需要动态传入…

【源码解析】Spring源码解读-bean的加载

Spring的整体流程其实就是通过配置 xml、注解将自定义bean类信息进行配置&#xff0c;然后通过BeanDefinitionReader读取配置信息&#xff0c;由Dom转换成xml解析成Docment。在通过加载的配置信息进行初始化Bean对象&#xff0c;然后在对象的前后进行处理&#xff0c;也就是不同…

2023-10-22

一、总线通信协议简介 总线是计算机系统中负责连接各个硬件的通信线路&#xff0c;它可以传输数据、地址和控制信号。通信协议是指双方实体完成通信所遵循的规则。总线通信协议是一种规定总线设备之间数据通信方式和方法的规则&#xff0c;它包括数据的通信方式、速率、格式、…

python爬虫之js逆向入门:常用加密算法的逆向和实践

一、强大的Chrome DevTools Chrome DevTools是一组内置于Google Chrome浏览器中的开发者工具&#xff0c;用于帮助开发人员调试、分析和优化Web应用程序。它提供了一系列功能强大的工具&#xff0c;用于检查和编辑HTML、CSS和JavaScript代码&#xff0c;监视网络请求、性能分析…

redis怎么设计一个高性能hash表

问题 redis 怎么解决的hash冲突问题 &#xff1f;redis 对于扩容rehash有什么优秀的设计&#xff1f; hash 目标是解决hash冲突&#xff0c;那什么是hash冲突呢&#xff1f; 实际上&#xff0c;一个最简单的 Hash 表就是一个数组&#xff0c;数组里的每个元素是一个哈希桶&…

ida81输入密码验证算法分析以及破解思路

本文分析了ida81对输入密码的验证流程&#xff0c;分别对输入密码到生成解密密钥、密码素材的生成过程以及文件数据的加密过程这三个流程进行分析&#xff0c;并尝试找一些可利用的破绽。很遗憾&#xff0c;由于水平有限&#xff0c;目前也只是有个思路未能完全实现&#xff0c…