java文件操作和IO流(详解)(๑•́ ₃ •̀๑)エー

news2024/11/17 4:47:35

目录

😄一.认识文件

1.1文件的概念与组成:

1.2树形结构组织与目录:

1.3文件路径:

😚二.文件系统操作

2.1File类概述:

2.2案例演示:

案例演示一:

 演示案例二:

🤪三.文件内容操作(“文件流”/ "IO"流)

3.1InputStream概述:

示例:读取文件中的数据

3.2OutputStream概述:

示例:项文件中写入数据

3.3Reader概述:

3.4Writer概述:

🤩四.小案例测试:

4.1案例一:

4.2案例二:

4.3.案例三:


😄一.认识文件

1.1文件的概念与组成:

我们先来认识狭义上的文件(File),对于硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公室桌上的一份份真实的文件一般。

⽂件除了有数据内容之外,还有⼀部分信息,例如⽂件名、⽂件类型、⽂件⼤⼩等并不作为⽂件的数 据而存在,我们把这部分信息可以视为⽂件的元信息。

1.2树形结构组织与目录:

同时,随着⽂件越来越多,对⽂件的系统管理也被提上了⽇程,如何进行⽂件的组织呢,⼀种合乎⾃ 然的想法出现了,就是按照层级结构进⾏组织⸺也就是我们数据结构中学习过的树形结构。这样, ⼀种专门用来存放管理信息的特殊⽂件诞⽣了,也就是我们平时所谓⽂件夹(folder)或者⽬录 (directory)的概念。

1.3文件路径:

  • 绝对路径

大家都知道,在我们平时使用计算机时要找到需要的文件就必须知道文件的位置,而表示文件的位置的方式就是路径,例如只要看到这个路径:c:/website/img/photo.jpg我们就知道photo.jpg文件是在c盘的website目录下的img子目录中。类似于这样完整的描述文件位置的路径就是绝对路径。

  • 相对路径

除了可以从根开始进⾏路径的描述,我们可以从任意结点出发,进⾏路径的描述,⽽这种描述⽅式就 被称为相对路径(relative path),相对于当前所在结点的⼀条路径。

举例:

file1的位置为:C:\ABC\path1\file1;(绝对路径)

file2的位置为:C:\ABC\path2\file2;(相对路径)

这时候让file1说出file2的位置则为:../path2/file2;两个点(..)表示回退到下一层。解释一下就是,file1在path1文件夹下,先点点,回退到ABC文件夹下,然后加上path2/file2,也就是 ../path2/file2,这就是相对路径了

😚二.文件系统操作

java通过java.io.File 类对一个文件(包括目录)进行抽象类的描述,注意,有File对象,并不代表真实存在该文件

2.1File类概述:

  • File类常见属性:

  • File类常见构造方法:

  •  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(Filedest)进⾏⽂件改名,也可以视为我们平 时的剪切、粘贴操作
booleancanRead()判断⽤⼾是否对⽂件有可读权限
booleancanWrite()判断⽤⼾是否对⽂件有可写权限

2.2案例演示:

案例演示一:

import java.io.File;
import java.io.IOException;
public class Test {
    public static void main(String[] args) throws IOException {
        File file = new File("../test.txt");
        //1.获取File对象的父目录文件路径
        System.out.println(file.getParent());
        //2.获取File对象的纯文件名称
        System.out.println(file.getName());
        //3.获取File对象的文件路径
        System.out.println(file.getPath());
        //4.获取File对象的绝对文件路径
        System.out.println(file.getAbsoluteFile());
        //5.过去File对象修饰过的绝对路径
        System.out.println(file.getCanonicalPath());
        //6.根据File对象,⾃动创建⼀个空⽂件。成功创建后返回true
        boolean ok = file.createNewFile();
        System.out.println(ok);
        //7.判断当前创建的文件是否存在
        System.out.println(file.exists());
        //8.判断File对象代表的⽂件是否是⼀ 个普通⽂件
        System.out.println(file.isFile());
        //9.判断File对象代表的⽂件是否是⼀个⽬录
        System.out.println(file.isDirectory());
        //10.删除该文件
        System.out.println(file.delete());
        //11.查看当前文件是否存在
        System.out.println(file.exists());
    }
}

运行结果:

..
test.txt
..\test.txt
D:\java_code\Test-java\..\test.txt
D:\java_code\test.txt
false
true
true
false
true
false

 演示案例二:

import java.io.File;
public class Demo {
    public static void main(String[] args) {
        File dir = new File("some-parent/some-dir");
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
        //创建File对象代表的⽬录
        System.out.println(dir.mkdir());
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
        //使用mkdir() 的时候,如果中间⽬录不存在,则⽆法创建成功;mkdirs()可以解决这个问题
        System.out.println("===================================");
        //创建File对象代表的⽬录,如果必要,会创建中间⽬录
        System.out.println(dir.mkdirs());
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
    }
}

运行结果:

false
false
false
false
false
===================================
true
true
false

🤪三.文件内容操作(“文件流”/ "IO"流)

IO简介:

IO 即 Input/Output,输入和输出。数据输入到计算机内存的过程即输入,反之输出到外部存储(比如数据库,文件,远程主机)的过程即输出。数据传输过程类似于水流,因此称为 IO 流。IO 流在 Java 中分为输入流和输出流,而根据数据的处理方式又分为字节流和字符流。

Java IO 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的。

  • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。

  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

3.1InputStream概述:

方法简介:

说明:

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

FileInputStream构造方法概述:

示例:读取文件中的数据

注:原本文本文件中只有两个汉字:你好

实现方式1

import java.io.*;

public class Demo {
    public static void main(String[] args) throws FileNotFoundException {
        try (InputStream inputStream = new FileInputStream("./src/iotest/test.txt")) {
            while (true) {
                int b = inputStream.read();
                if (b == -1) {
                    // 读取完毕了
                    break;
                }
                // 表示字节, 更习惯使用 十六进制 打印显示.
                System.out.printf("0x%x\n", b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

实现方式2:

import java.io.*;

public class Demo1 {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("./src/iotest/test.txt")) {
            while (true) {
                byte[] buffer = new byte[1024];
                // n 返回值表示 read 操作, 实际读取到多少个字节.
                int n = inputStream.read(buffer);
                System.out.println(n);
                if (n == -1) {
                    break;
                }
                for (int i = 0; i < n; i++) {
                    System.out.printf("0x%x\n", buffer[i]);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

3.2OutputStream概述:

方法简介:

示例:项文件中写入数据

public class Demo2 {
    public static void main(String[] args) {
        try (OutputStream outputStream = new FileOutputStream("./src/iotest/test.txt", true)) {
            // outputStream.write(97);
            byte[] buffer = new byte[] { (byte)0xe4, (byte)0xbd, (byte)0xa0, (byte)0xe5, (byte)0xa5, (byte)0xbd };
            //1.直接从0位置开始写6个单位长度的字符
            outputStream.write(buffer, 0, 6);
            //2.一个一个的写
            outputStream.write(0xe4);
            outputStream.write(0xbd);
            outputStream.write(0xa0);
            outputStream.write(0xe5);
            outputStream.write(0xa5);
            outputStream.write(0xbd);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

3.3Reader概述:

Reader用于从源头(通常是文件)读取数据(字符信息)到内存中,java.io.Reader抽象类是所有字符输入流的父类。

Reader 用于读取文本, InputStream 用于读取原始字节。

Reader 常用方法:

  • read() : 从输入流读取一个字符。
  • read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中,等价于 read(cbuf, 0, cbuf.length)
  • read(char[] cbuf, int off, int len):在read(char[] cbuf) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字符数)。
  • skip(long n):忽略输入流中的 n 个字符 ,返回实际忽略的字符数。
  • close() : 关闭输入流并释放相关的系统资源。

3.4Writer概述:

Writer用于将数据(字符信息)写入到目的地(通常是文件),java.io.Writer抽象类是所有字符输出流的父类。

Writer 常用方法:

  • write(int c) : 写入单个字符。
  • write(char[] cbuf):写入字符数组 cbuf,等价于write(cbuf, 0, cbuf.length)
  • write(char[] cbuf, int off, int len):在write(char[] cbuf) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字符数)。
  • write(String str):写入字符串,等价于 write(str, 0, str.length())
  • write(String str, int off, int len):在write(String str) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字符数)。
  • append(CharSequence csq):将指定的字符序列附加到指定的 Writer 对象并返回该 Writer 对象。
  • append(char c):将指定的字符附加到指定的 Writer 对象并返回该 Writer 对象。
  • flush():刷新此输出流并强制写出所有缓冲的输出字符。
  • close():关闭输出流释放相关的系统资源。

🤩四.小案例测试:

4.1案例一:

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

代码详解:

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

public class IOTest1 {
    //递归扫描文件
    public static void scan(File currentFile,String key){
        //如果当前文件不是目录,直接返回
        if(!currentFile.isDirectory()){
            return ;
        }

        File[] files = currentFile.listFiles();
        //如果当前文件不存在或者当前文件为空时,直接返回
        if(files == null || files.length == 0){
            return ;
        }

        //递归遍历该目录下的文件
        for(File f : files){
            //如果是普通文件,判断文件名是否符合要求并提示用户删除
            if(f.isFile()){
                doDelete(f,key);
            }else{
                //如果是目录,继续递归
                scan(f,key);
            }
        }
    }

    private static void doDelete(File f, String key) {
        if(!f.getName().contains(key)){
            //文件名中不包含指定的关键字
            return ;
        }
        //提示用户,是否确认要删除
        Scanner scanner = new Scanner(System.in);
        System.out.println("查找到一个对应的文件路径: " + f.getAbsolutePath());
        System.out.print("这个文件路径 " + f.getAbsolutePath() + " 是否确认要删除 Y/N -> ");
        String choice = scanner.next();
        if(choice.equals("Y") || choice.equals("y")){
            f.delete();
        }
    }

    public static void main(String[] args) {
        System.out.print("请输入要搜索的路径:");
        Scanner scanner = new Scanner(System.in);
        String rootPath = scanner.next();
        File rootFile = new File(rootPath);
        if(!rootFile.isDirectory()){
            System.out.println("输入的文件路径不存在");
            return ;
        }
        System.out.print("请输入要删除的文件名的关键字:");
        String key = scanner.next();
        //进行递归查找
        scan(rootFile,key);
    }
}

运行结果(这里查找到的文件路径有许多,展示部分):

4.2案例二:

要求:实现复制文件, 把一个文件里的每个字节都读出来, 写入到另一个文件中

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

public class IOTest2 {
    // 实现复制文件, 把一个文件里的每个字节都读出来, 写入到另一个文件中
    public static void main(String[] args) {
        // 1. 输入路径, 并且做校验
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入源文件的路径: ");
        String srcPath = scanner.next();
        File srcFile = new File(srcPath);
        if (!srcFile.isFile()) {
            System.out.println("源文件路径有误!");
            return;
        }
        System.out.print("请输入目标文件的路径: ");
        String destPath = scanner.next();
        File destFile = new File(destPath);
        if (!destFile.getParentFile().isDirectory()) {
            System.out.println("目标文件的路径有误!");
            return;
        }

        // 2. 执行复制的过程
        try (InputStream inputStream = new FileInputStream(srcFile);
             OutputStream outputStream = new FileOutputStream(destFile)) {
            while (true) {
                byte[] buffer = new byte[1024];
                int n = inputStream.read(buffer);
                System.out.println("n = " + n);
                if (n == -1) {
                    break;
                }
                // 需要把 buffer 写入到 outputStream 中
                outputStream.write(buffer, 0, n);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果(原本test1.txt中数据为“你好世界”,而test2.txt中为空,复制完成后):

4.3.案例三:

要求:扫描指定⽬录,并找到名称或者内容中包含指定字符的所有普通⽂件(不包含⽬录)

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Scanner;

public class IOTest3 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要查找的目录: ");
        String srcString = scanner.next();
        File srcFile = new File(srcString);
        if(!srcFile.isDirectory()){
            System.out.println("输入的文件目录有误!");
            return ;
        }

        System.out.print("请输入要查询的关键词: ");
        String key = scanner.next();
        scan(srcFile,key);
    }

    private static void scan(File srcFile, String key) {
        if(!srcFile.isDirectory()){
            //如果不是目录,结束递归
            return ;
        }

        File[] files = srcFile.listFiles();
        if(files == null || files.length == 0){
            return ;
        }
        //递归遍历目录下的文件
        for(File f : files){
            if(f.isFile()){
                //进行后续的查询操作
                doReserch(f,key);
            }else{
                scan(f,key);
            }
        }
    }

    private static void doReserch(File f, String key) {
        //打开文件,读取文件内容,判断文件内容中是否包含 key
        StringBuilder stringBuilder = new StringBuilder();
        try(Reader reader = new FileReader(f)){
            char[] buffer = new char[1024];
            while(true){
                int n = reader.read(buffer);
                if(n == -1){
                    break;
                }
                String s = new String(buffer,0,n);
                stringBuilder.append(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        if(stringBuilder.indexOf(key) == -1){
            //没找到
            return ;
        }
        //找到了
        System.out.println("找到匹配文件: " + f.getAbsolutePath());
    }
}

运行结果:

参考文章:

Java IO 基础知识总结 | JavaGuide

结语: 写博客不仅仅是为了分享学习经历,同时这也有利于我巩固知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力!

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

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

相关文章

【Python系列】signal信号处理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Unix 系统

各种各样的系统优缺点-CSDN博客 目录 █ 操作系统的诞生 █ UNIX的诞生 █ Linux的诞生 █ Linux和Unix的关系 █ Linux的发行版 说到操作系统&#xff0c;大家都不会陌生。我们天天都在接触操作系统——用台式机或笔记本电脑&#xff0c;使用的是windows和macOS系统&…

Docker续2:docker部署前端项目

一、部署前端页面 [rootlocalhost ~]# ls //导入dist项目 anaconda-ks.cfg centos_httpd.tar centos_nginx centos.tar centos_yum.tar dist [rootlocalhost ~]# docker pull mysql //下载mysql [rootlocalhost ~]# docke…

深入垃圾回收:理解GC的核心算法与实现

垃圾回收&#xff08;Garbage Collection&#xff0c;GC&#xff09;是现代编程语言中一项关键技术。它不仅解决了内存管理中的诸多问题&#xff0c;还为开发者提供了一个更高效、更安全的编程环境。本文将深入探讨GC的起源、主要算法以及这些算法在不同编程语言中的具体实现。…

你好GPT-4o,程序员如何通过GPT-4o提升自己的编码能力

目录 round 1&#xff1a;图片识别能力ChatGPT4oClaude3.5 Sonnet图片识别能力小结&#xff1a;图片识别能力&#xff0c;ChatGPT4o完胜。 round 2&#xff1a;代码能力ChatGPT4oClaude3.5 Sonnet代码能力小结&#xff1a;代码能力&#xff0c;Claude3.5 Sonnet小胜。 round 3&…

Git之1.0版本重要特性及用法实例(五十二)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者. 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列…

HCS-网络服务

一、华为云Stack网络服务概览 1.网络服务包括&#xff1a;虚拟私有云、弹性负载均衡、弹性IP、网络ACL、虚拟专用网络、云专线、VPC终端节点、云解析 2.华为云Stack网络服务全景图&#xff1a; 二、云上通用网络服务 1.虚拟私有云 虚拟私有云&#xff08;Virtual Private Clo…

C++系列-STL容器之stack

STL容器之stack stack容器的概念stack的构造函数及接口stack的注意事项 浣溪沙簌簌衣巾落枣花 苏轼 簌簌衣巾落枣花&#xff0c;村南村北响缲车。牛衣古柳卖黄瓜。 酒困路长惟欲睡&#xff0c;日高人渴漫思茶。敲门试问野人家。 stack容器的概念 stack容器是一种容器适配器(通…

阿里云数智服务创新挑战赛总决赛铜奖比赛攻略_NJUSME队

关联比赛: 阿里云数智服务创新挑战赛——服务调度比赛 下面我们将从赛题场景、核心算法以及算法的场景拓展对我们的解决方案进行说明。 1 赛题场景 首先对赛题场景进行分析。我们建立流程图&#xff0c;梳理整体的调度流程。首先客户会先进入系统&#xff0c;定位问题明确问…

cesium 雪积压效果(customShader)

cesium 雪积压效果 原理&#xff1a;不同于后处理&#xff0c;这里采用的是customShader 优点&#xff1a;不用模型法线&#xff0c;仅模型雪覆盖 效果图

Qt (12)【Qt窗口 —— 消息对话框 QMessageBox 】

阅读导航 引言一、消息对话框简介二、问题提示消息对话框创建三、信息提示消息对话框创建四、警告信息消息对话框创建五、错误提示消息对话框创建 引言 在上一篇文章中&#xff0c;我们一同探索了Qt框架中窗口与对话框的奥秘&#xff0c;特别是那些由Qt内置提供的、功能丰富且…

公安的实名认证如何对接?

实名认证已成为许多在线服务和应用的必要环节。本文将为您详细介绍如何对接公安的实名认证系统,包括主要合作方、对接流程以及技术细节。 1. 中盾安信简介 北京中盾安信科技发展有限公司(简称"中盾安信")是公安部第一研究所的全资子公司。作为国家"互联网"…

这 3 个开源项目 牛逼的飞起

分享几个 git 上好玩的应用&#xff0c;对独立开发程序感兴趣的小伙伴欢迎关注后期圈&#xff5e; 点个赞呗 01个性化桌面状态栏的神器 开源地址&#xff08;自行添加网址&#xff09;&#xff1a;/polybar/polybar 一个让无数开发者和桌面美化爱好者爱不释手的开源项&#x…

VBA学习(67):Excel VBA 提取数字/自定义工作表函数/正则表达式/批量提取电话号码

正则表达式&#xff08;Regular Expression&#xff09;&#xff0c;又称为“正则式”、“规则表达式”、“常规表示法”&#xff0c;是一种用来匹配、查找、替换字符串的工具。它通过一定的符号、元字符和操作符的组合来表达一个特定的模式&#xff0c;从而匹配符合该模式的字…

opencv实战项目十八:Gabor滤波器提取布料纹理

文章目录 前言一、Gabor简介二、cv2.getGaborKernel&#xff08;&#xff09;三&#xff0c;效果&#xff1a; 前言 在计算机视觉和图像处理领域&#xff0c;纹理分析一直是一个热门且富有挑战性的话题。纹理&#xff0c;作为图像中的一种重要视觉特征&#xff0c;不仅承载着丰…

关于BitConverter.GetBytes取得的值是反的问题

通过百度查询450000转16进制&#xff0c;我们得到的值是6DDD0&#xff0c; 在前面补零之后的值应该是0006DDD0。如下图所示。 实际上我们用BitConverter.GetBytes 方法转换450000为byte[] 的时候, 转换后的值用16进制显示为D0DD0600(因为我这里是一个通讯协议的数据传输前转换&…

回归预测 | Matlab实现GWO-BP-Adaboost灰狼算法优化BP神经网络集成学习多输入单输出回归预测

回归预测 | Matlab实现GWO-BP-Adaboost灰狼算法优化BP神经网络集成学习多输入单输出回归预测 目录 回归预测 | Matlab实现GWO-BP-Adaboost灰狼算法优化BP神经网络集成学习多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现GWO-BP-Adaboost灰…

GMS——利用 ChatGPT 和扩散模型进行制造业革命

概述 论文地址&#xff1a;https://arxiv.org/abs/2405.00958 研究介绍了生成式制造系统&#xff08;GMS&#xff09;&#xff0c;并表明这些系统能有效管理和协调自主制造资产&#xff0c;提高它们对不同生产目标和人类偏好的响应能力和灵活性。 与传统的显式建模不同&#…

嵌入式Linux学习笔记-Linux基础操作

一、Linux 目录结构 二、文件基础操作 Linux 命令一般由三部分组成&#xff0c;命令 选项 参数。 1、pwd&#xff1a;列出当前所在路径 pwd //列出当前所在目录 2、cd&#xff1a;切换路径 cd /home/boot //切换路径为/home/boot cd .. //返回上一级目录…