当前位置: 首页 > news >正文

【IO】文件操作基础知识

目录

1.文件的操作:

2.文件内容的读写—数据流:

3.文件操作练习:


1.文件的操作:

  1. 文件分为狭义上的文件和广义的文件。
  2. 狭义上的文件:存储在硬盘上的数据,以“文件”为单位进行组织。文件夹也叫做目录。
  3. 通过“路径”的概念来描述一个文件在电脑上的具体位置。路径分为绝对路径(每个 / 间隔的部分都是目录)和相对路径(需要有基准)。
  4. 相对路径中 ./表示当前目录(./qq/Bin/QQ.exe);使用 ../ 表示返回到上级目录
  5. I(input)O(output),输入和输出的方向是以CPU/内存为中心。输入就是将外部设备(键盘)的数据放到内存里。
  6. File类;注意:有File对象不代表有真实存在该对象。File类的构造方法常用File(路径),这里的路径可以是绝对路径还可以是相对路径。一个file对象就是一个文件或目录。
    File file = new File("..//helloworld.txt");//并不要求该文件真实存在
    返回值类型方法签名说明
    StringgetName()返回File对象纯文件名称
    booleanisDirectory()判断是不是目录
    booleanisFile()判断是不是普通文件
    booleancreateNewFile()创建文件,成功后返回true
    booleandelete()删除该文件,成功后返回true
    voiddeleteOnExit()进程退出时才会删除文件
    booleanmkdir()创建目录
    booleanmkdirs()创建多级目录
    booleanrenameTo()重命名

2.文件内容的读写—数据流:

  1. 读操作:InputStream;从外部设备读取到内存上。
    //InputStream是一个抽象类,不具体,不能实例化,所以需要用到FileInputStream
    //下面这个过程就相当于打开文件!想要读写文件就需要打开文件~
    InputStream inputStream = new FileInputStream("hello.txt");
    返回值类型方法签名说明
    intread()读取一个字节的数据,返回-1代表读完了
    intread(byte[ ] b)读取b.length字节数据放到b中,返回读到的数量,-1代表已经读完了
    intread(byte[ ] b, int m, int n)读取n-m个字节到b中
    voidclose()关闭字节流
  2. //1.读操作:无
    public static void main(String[] args) throws IOException {
            InputStream inputStream = new FileInputStream("hello.txt");
            while(true){
                int ret = inputStream.read();
                if(ret == -1){
                    break;
                }
                System.out.println(ret);
            }
            inputStream.close();
    }
    //2.读操作:使用Scanner来读数据
    public static void main(String[] args) throws IOException {
            InputStream inputStream = new FileInputStream("./hello.txt");
            //scanner搭配inputStream使用,读操作
            Scanner scanner = new Scanner(inputStream);
    
            while(scanner.hasNext()){
                System.out.println(scanner.next());
            }
    
            inputStream.close();
    }
    //3.读操作:使用byte数组
    public static void main(String[] args) throws IOException {
            try(InputStream inputStream = new FileInputStream("hello.txt")){
                byte[] ret = new byte[1024];
                int len = 0;
                while(true){
                     len = inputStream.read(ret);
                    if(len == -1){
                        break;
                    }
                    for (int i = 0; i < len; i++) {
                        System.out.println(ret[i]);
                    }
                }
            }
    }
    //4.读操作:使用try和scanner
    public static void main(String[] args) throws IOException {
            try(InputStream inputStream = new FileInputStream("./hello.txt");
                  Scanner scanner = new Scanner(inputStream)){
                while(scanner.hasNext()){
                    String ret = scanner.next();
                    System.out.println(ret);
                }
            }
    }
  3. 写:OutputStream;
    //OutputStream是一个抽象类,不具体,不能实例化,所以需要用到FileOutputStream
    //使用OutputStream写文件的时候,只要文件打开成功,就会把文件原来的内容清空
    OutputStream outputStream = new FileOutrputStream("./hello.txt");
    返回值类型方法签名说明
    voidwrite(int b)写入一个字符将b这个字符数组中的数据全部写入
    voidwrite(byte[ ] b)将b这个字符数组中的数据全部写入
    intwrite(byte[ ] b, int m, int n)将b这个字符数组中的数据从m开始写入
    voidclose()关闭字节流
    voidflush()刷新缓冲区
  4. //1.写操作
    public static void main(String[] args) throws IOException {
            OutputStream outputStream = new FileOutputStream("./hello.txt");
            //打开文件后,会先把文件内容清空
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
    
            outputStream.close();
    }
    //2.写操作:使用PrintWriter来写操作
    public static void main(String[] args) throws IOException {
            OutputStream outputStream = new FileOutputStream("./hello.txt");
    
            PrintWriter writer = new PrintWriter(outputStream);
    
            writer.print(45);
            writer.print('c');
            writer.println();
    
            //一定要刷新缓冲区
            outputStream.flush();
    
            //一定要关闭文件,writer.close()!!!
            writer.close();
    }
    //3.写操作:使用try和PrintWriter来写操作
    public static void main(String[] args) throws IOException {
            try(OutputStream outputStream = new FileOutputStream("./hello.txt");
                PrintWriter writer = new PrintWriter(outputStream)){
    
                writer.println();
                writer.print('s');
    
                writer.flush();
            }
    }
    //4.写操作:使用OutputStreamWriter和PrintWriter来写
    public static void main(String[] args) throws IOException {
            try(OutputStream outputStream = new FileOutputStream("./hello.txt");
                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
                PrintWriter printWriter = new PrintWriter(outputStreamWriter)){
                
                printWriter.println();
                printWriter.print(1);
                printWriter.print(12);
                printWriter.print(13);
    
                printWriter.flush();
            }
    }
  5. 刷新缓冲区:OutputStream为了减少设备操作的次数,写数据时会将数据暂时写入缓冲区中,直到满足条件才写到内存上。因此为了保证数据不会遗留在缓冲区上,我们需要用到刷新缓存区flash()的操作来将数据刷到设备上。 

  6. 文件内容操作后一定要将文件close,否则会造成文件资源泄露,类比于图书馆借书(一伙人直只借不还,图书馆的书不就越来越少了嘛~)。

    为什么需要close文件???
    1.每个进程都对应着PCB,PCB里面有一个字段,文件描述符表
    2.同一个进程里面多个PCB可能同时使用一份文件描述符表
    3.文件描述符表相当于一个数组,每次打开一个文件,都会在表里创建一个项
    4.如果关闭则会把对应的项给释放掉
    5.如果不关闭,意味着这个项一直占着位置,
    6.如果持续打开文件且从来不关就会导致表项(数组里的元素)被耗尽
    7.导致后续文件在打开文件就会打开失败
    8.所以需要保证代码执行完关闭文件

3.文件操作练习:

1.扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件 

思路:

1.先让用户输入要扫描的路径和要查找的字
2.遍历目录,找到名字包含的的文件
3.询问用户是否删除

代码:

//扫描目录,找到包含指定字符的所有普通文件,找到后询问是否要删除
public class Demo {
    public static void main(String[] args) throws IOException {
        //1.让用户输入必要的信息
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要扫描的路径:");
        File rootDir = new File(scanner.next());
        if(!rootDir.isFile()){
            System.out.println("输入的目录有错误!!!");
            return;
        }
        System.out.println("请输入要查找的关键字:");
        String toDelete = scanner.next();


        //2.遍历目录
        scanDir(rootDir,toDelete);

    }

    private static void scanDir(File rootDir, String toDelete) throws IOException {
        System.out.println("当前访问: "+rootDir.getCanonicalPath());
        File[] files = rootDir.listFiles();
        if(files == null){
            //说明目录是个空的目录
            return;
        }
        for (File f : files) {
            if(f.isDirectory()){
                scanDir(f,toDelete);
            }else{
                checkDelete(f,toDelete);
            }
        }
    }

    private static void checkDelete(File f, String toDelete) throws IOException {
        if(f.getName().contains(toDelete)){
            System.out.println("该单词"+toDelete+" 被 "+f.getCanonicalPath()+"包含了,是否要删除?(Y/N)" );
            Scanner scanner = new Scanner(System.in);
            String choice = scanner.next();
            if(choice.equals("Y") || choice.equals("y")){
                f.delete();
            }
        }
    }
}

2.将普通的文件复制一份

思路:

把第一个文件打开,将里面的内容逐个字节的读取出来,写入到第二个文件中

代码:

//普通文件的复制
public class Demo {
    public static void main(String[] args) throws IOException {
        //1.输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要复制的源文件:");
        File srcFile = new File(scanner.next());

        System.out.println("请输入目标文件:");
        File destFile = new File(scanner.next());

        if(!srcFile.isFile()){
            System.out.println("输入的源文件有错误!!!");
            return;
        }
        if(!destFile.getParentFile().isDirectory()){
            System.out.println("输入的目标文件有误!!!");
            return;
        }

        //2.打开目标文件,按照字节读取写入到目标文件中

        try(InputStream inputStream = new FileInputStream(srcFile);
            OutputStream outputStream = new FileOutputStream(destFile)){
            while(true){
                int ret = inputStream.read();
                if(ret == -1){
                    break;
                }
                outputStream.write(ret);
            }
        }

    }
}

3.扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)

思路:

1.先让用户输入要扫描的路径和要查找的字
2.遍历目录,找到名字和内容都包含的文件
3.询问用户是否删除

代码:

//扫描文件,判断其中是否包含关键字
public class Demo {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要扫描的路径:");
        File rootDir = new File(scanner.next());

        if(!rootDir.isFile()){
            System.out.println("输入的路径有问题!");
            return;
        }
        System.out.println("请输入要搜索的关键字:");
        String toFind = scanner.next();

        //2.遍历
        scanDir(rootDir,toFind);
    }

    private static void scanDir(File rootDir, String toFind) throws IOException {
        System.out.println("当前路径:"+rootDir.getCanonicalPath());
        File[] files = rootDir.listFiles();
        if(files == null){
            return;
        }
        for(File f : files){
            if(f.isDirectory()){
                scanDir(f,toFind);
            }else{
                checkDelete(f,toFind);
            }
        }

    }

    private static void checkDelete(File f, String toFind) throws IOException {
        //先检查文件名
        if(f.getName().contains(toFind)){
            System.out.println(f.getCanonicalPath() + "文件名中包含 " + toFind+" 是否删除(Y/N)");
        }
        try(InputStream inputStream = new FileInputStream(f)){
            StringBuilder sb = new StringBuilder();
            Scanner scanner = new Scanner(inputStream);

            while(scanner.hasNextLine()){
                sb.append(scanner.nextLine() + "\n");
            }
            if(sb.indexOf(toFind) > -1){
                System.out.println(f.getCanonicalPath() + "文件内容中包含 " + toFind+" 是否删除(Y/N)");

            }
        }
    }
}

如果对您有帮助的话,

不要忘记点赞+关注哦,蟹蟹

如果对您有帮助的话,

不要忘记点赞+关注哦,蟹蟹

如果对您有帮助的话,

不要忘记点赞+关注哦,蟹蟹

相关文章:

  • Win11安装怎么跳过TPM-Win11安装跳过TPM的方法介绍
  • 【沃趣科技】初探MySQL迁移到ClickHouse
  • EndNote使用技巧之引用文献信息的导入与修改
  • java怎么连接数据库mysql
  • AI绘画逆着玩火了,敢不敢发自拍看AI如何用文字形容你?
  • 是时候掌握SpringMVC源码了-初探篇
  • 上手Python之set(集合)
  • Visual Studio 2022开发Arduino详述
  • 【机器人定位引导中的机器视觉技术】
  • 零售商贩mysql表设计:主题信息表(theme)
  • 本文带你了解透彻云计算(前世,今生,未来)
  • ARM发布Cortex-X3和Cortex-A715
  • 麻雀算法极限学习机SSA-ELM回归预测及其MATLAB代码实现
  • 云原生DevOps篇:jenkins发送通知到企业微信机器人
  • LeetCode337:打家劫舍III
  • Brief introduction of how to 'Call, Apply and Bind'
  • C++11: atomic 头文件
  • JavaScript 一些 DOM 的知识点
  • jquery cookie
  • Js基础——数据类型之Null和Undefined
  • Koa2 之文件上传下载
  • php中curl和soap方式请求服务超时问题
  • Python 反序列化安全问题(二)
  • scala基础语法(二)
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 大数据与云计算学习:数据分析(二)
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 基于webpack 的 vue 多页架构
  • 来,膜拜下android roadmap,强大的执行力
  • 前端性能优化——回流与重绘
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 实现简单的正则表达式引擎
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 我建了一个叫Hello World的项目
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 译米田引理
  • 用 Swift 编写面向协议的视图
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​比特币大跌的 2 个原因
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (3)(3.5) 遥测无线电区域条例
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (二开)Flink 修改源码拓展 SQL 语法
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (十六)一篇文章学会Java的常用API
  • (五)Python 垃圾回收机制
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功