【Java】文件操作和IO

news2024/11/17 6:30:01

文件操作和IO

  • 文件
    • 树形结构组织和目录
    • 文件路径
  • Java中操作文件
    • File
  • 文件内容的读写(数据流)
    • Reader和Writer
      • 字符输入流 Reader
      • 字符输出流 Writer
      • FileReader 和 FileWriter
        • FileReader
        • FileWriter
    • InputStream和OutputStream
      • InputStream
        • FileInputStream
        • FileOutputStream
  • 小程序
    • 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录)
    • 进行普通文件的复制

文件

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

树形结构组织和目录

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

文件路径

如何在文件系统中如何定位我们的一个唯一的文件就成为当前要解决的问题,但这难不倒计算机科学
家,因为从树型结构的角度来看,树中的每个结点都可以被一条从根开始,一直到达的结点的路径所描
述,而这种描述方式就被称为文件的绝对路径(absolute path)

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

Java中操作文件

File

File类是用于处理文件和目录的基本操作的类。它提供了许多方法来创建、删除、重命名、检查文件或目录的存在性、获取文件属性等。

要使用File类,首先需要实例化一个File对象,该对象可以表示文件或目录的路径。

  1. 创建文件或目录:

**File file = new File(“path/to/file”);:**使用指定的路径创建一个File对象。
file.mkdir():创建一个目录。
file.createNewFile():创建一个新文件。

  1. 删除文件或目录:

file.delete():删除文件或目录。
file.deleteOnExit():在JVM退出时删除文件或目录。

  1. 重命名文件或目录:

file.renameTo(newName):将文件或目录重命名为新名称。

  1. 判断文件或目录是否存在:

file.exists():检查文件或目录是否存在。
file.isFile():检查是否为文件。
file.isDirectory():检查是否为目录。

  1. 获取文件或目录的属性:

file.getName():获取文件或目录的名称。
file.getAbsolutePath():获取文件或目录的绝对路径。
file.length():获取文件的长度(字节数)。
file.lastModified():获取文件或目录的最后修改时间。

  1. 遍历目录:

file.listFiles():返回目录下的所有文件和子目录的File对象数组。

构造方法
在这里插入图片描述

文件内容的读写(数据流)

在这里插入图片描述

(抽象基类)输入流输出流
字节流InputStreamOutputStream
字符流ReaderWriter

Java的IO流共涉及40多个类,实际上非常规则,都是由上面四个抽象类派生的

如果衍生自InputStream或者Reader,就可以使用read方法来读数据
如果衍生自OutputStream或者Writer,就可以使用write方法来写数据

文件操作的核心步骤就是打开文件,关闭文件,读文件,写文件

其中关闭文件是非常重要的,一个进程打开一个文件,要在系统中申请一定资源的(占用进程里pcb里文件描述符表的一个表项,且这个表长度有限,不会扩容),此时如果不释放资源,就会出现文件资源泄露的问题.

Reader和Writer

Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。不能操作图片,视频等非文本文件。

常见的文本文件有如下的格式:.txt、.java、.c、.cpp、.py等

注意:.doc、.xls、.ppt这些都不是文本文件。

字符输入流 Reader

java.io.Reader抽象类是表示用于读取字符流的所有类的父类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。

  • public int read(): 从输入流读取一个字符。 虽然读取了一个字符,但是会自动提升为int类型。返回该字符的Unicode编码值。如果已经到达流末尾了,则返回-1。
  • public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。每次最多读取cbuf.length个字符。返回实际读取的字符个数。如果已经到达流末尾,没有数据可读,则返回-1。
  • public int read(char[] cbuf,int off,int len):从输入流中读取一些字符,并将它们存储到字符数组 cbuf中,从cbuf[off]开始的位置存储。每次最多读取len个字符。返回实际读取的字符个数。如果已经到达流末尾,没有数据可读,则返回-1。
  • public void close() :关闭此流并释放与此流相关联的任何系统资源。

注意:当完成流的操作时,必须调用close()方法,释放系统资源,否则会造成内存泄漏。

字符输出流 Writer

java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。

  • public void write(int c) :写出单个字符。
  • public void write(char[] cbuf) :写出字符数组。
  • public void write(char[] cbuf, int off, int len) :写出字符数组的某一部分。off:数组的开始索引;len:写出的字符个数。
  • public void write(String str) :写出字符串。
  • public void write(String str, int off, int len) :写出字符串的某一部分。off:字符串的开始索引;len:写出的字符个数。
  • public void flush() :刷新该流的缓冲。
  • public void close() :关闭此流。

注意:当完成流的操作时,必须调用close()方法,释放系统资源,否则会造成内存泄漏。

FileReader 和 FileWriter

FileReader

java.io.FileReader 类用于读取字符文件,构造时使用系统默认的字符编码和默认字节缓冲区。

  • FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。
  • FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的名称。

举例,读取文件中的字符数据,显示在控制台上

public class Demo1 {
    //读取文件中的内容,展示在控制台
    public static void main(String[] args) throws IOException {
        File file = new File("D:\\code\\2023_java\\IO\\src\\hello.txt");
        System.out.println(file.isFile());
        try(FileReader fr = new FileReader(file)){
            int data;
            while ((data = fr.read()) != -1){
                System.out.print((char)data);
            }
        }
    }
}
public class Demo2 {
    public static void main(String[] args) throws IOException {
        File file = new File(".\\src\\hello.txt");
        try(FileReader fr = new FileReader(file)){
            char[] buf = new char[5];
            //记录每次读入的字符个数
            int len;
            while ((len =fr.read(buf)) != -1){
                for (int i = 0; i < len; i++) {
                    System.out.print(buf[i]);
                }
            }
        }
    }
}

在这里插入图片描述

FileWriter

java.io.FileWriter 类用于写出字符到文件,构造时使用系统默认的字符编码和默认字节缓冲区。

  • FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。
  • FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。
  • FileWriter(File file,boolean append): 创建一个新的 FileWriter,指明是否在现有文件末尾追加内容。

对于输入流来说,File类的对象必须在物理磁盘上存在,否则执行就会报FileNotFoundException。如果传入的是一个目录,则会报IOException异常

这里是引用对于输出流来说,File类的对象是可以不存在的。
如果File类的对象不存在,则可以在输出的过程中,自动创建File类的对象

如果File类的对象存在,
如果调用FileWriter(File file)或FileWriter(File file,false),输出时会新建File文件覆盖已有的文件
如果调用FileWriter(File file,true)构造器,则在现有的文件末尾追加写出内容。

InputStream和OutputStream

如果我们读取或写出的数据是非文本文件,则Reader、Writer就无能为力了,必须使用字节流。

InputStream

java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。

  • public void write(int b) :将指定的字节输出流。虽然参数为int类型四个字节,但是只会保留一个字节的信息写出。
  • public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。
  • public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
  • public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void close() :关闭此输出流并释放与此流相关联的任何系统资源。

说明:close()方法,当完成流的操作时,必须调用此方法,释放系统资源。

FileInputStream

java.io.FileInputStream 类是文件输入流,从文件中读取字节。

  • FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
  • FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

FileOutputStream

java.io.FileOutputStream 类是文件输出流,用于将数据写出到文件。

  • public FileOutputStream(File file):创建文件输出流,写出由指定的 File对象表示的文件。
  • public FileOutputStream(String name): 创建文件输出流,指定的名称为写出文件。
  • public FileOutputStream(File file, boolean append): 创建文件输出流,指明是否在现有文件末尾追加内容。

小程序

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

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

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

    /**
     *
     * @param rootDir 根目录文件
     * @param token   要查找的字符
     * @param result  结果集
     */
    private static void scanDir(File rootDir, String token, List<File> result){
        File[] files = rootDir.listFiles();
        //将根目录下的所有文件放在files中
        if(files == null || files.length == 0){
            //当根目录为空时,直接返回,
            return;
        }
        for (File file: files) {
            if(file.isDirectory()){
                //如果这个文件是一个文件夹,那么就递归调用
                scanDir(file,token,result);
            }else {
                //如果是一个普通文件,就检查这个文件的文件名是否包含我们要找的字符
                //如果包含,就把这个文件放在结果集中
                if (file.getName().contains(token)){
                    result.add(file.getAbsoluteFile());
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要扫描的根目录");
        String rootFirPath = scanner.nextLine();

        File rootDir = new File(rootFirPath);
        if(!rootDir.isDirectory()){
            System.out.println("您输入的根目录不存在或者不是目录,退出");
            return;
        }

        System.out.println("请输入要查找的文件名中的字符");
        String token = scanner.nextLine();
        List<File> result = new ArrayList<>();
        scanDir(rootDir,token,result);


        System.out.println("共找到了符合条件的文件 " + result.size() + " 个,它们分别 是");
        for (File file: result) {
            System.out.println(file.getCanonicalPath());

        }
    }
}

进行普通文件的复制

public class Demo4 {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要复制的文件");
        String sourcePath = scanner.next();
        //通过输入的文件名构造出一个File对象
        File sourceFile = new File(sourcePath);
        if(!sourceFile.exists()){
            //若输入的文件不存在,直接退出
            System.out.println("此文件不存在,请确认路径是否正确");
            return;
        }
        if(!sourceFile.isFile()){
            //判断文件是否是一个普通文件
            System.out.println("文件不是一个普通文件,请确认路径是否正确");
            return;
        }
        System.out.println("请输入要复制到的目标路径");
        String destPath = scanner.next();
        File destFile = new File(destPath);
        if(destFile.isFile()){
            if(destFile.isDirectory()){
                System.out.println("目标路径已经存在,并且是一个目录,请确认路径是否正确");
                return;
            }
            if (destFile.isFile()){
                System.out.println("目标路径已经存在.是否进行覆盖?y/n");
                String ans = scanner.next();
                if(!ans.toLowerCase().equals("y")){
                    System.out.println("停止复制");
                    return;
                }
            }
            try(InputStream is = new FileInputStream(sourceFile);
            OutputStream os = new FileOutputStream(destFile)){
                byte[] buf = new byte[1024];
                int len;
                while (true){
                    len = is.read(buf);
                    if(len == -1){
                        break;
                    }
                    os.write(buf,0,len);
                }
                os.flush();
            }
        }
        System.out.println("复制结束");
    }
}

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

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

相关文章

Vue3实现24小时倒计时

方法一:时间戳(24小时以内,毫秒为单位)转成时间,并且倒计时 效果预览: <script> // 剩余时间的时间戳,24小时的时间戳是86400000 const exTime = ref(86400000) // 支付时间期限 const payTime = ref() const maxtime = ref(0) //倒计时(时间戳,毫秒单位)转换成秒…

java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发

​ ​工程项目管理系统是指从事工程项目管理的企业&#xff08;以下简称工程项目管理企业&#xff09;受业主委托&#xff0c;按照合同约定&#xff0c;代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 如今建筑行业竞争激烈&#xff0c;内卷严重&#xff0c…

OPENCV实现ORB特征检测

# -*- coding:utf-8 -*- """ 作者:794919561 日期:2023/8/31 """ import cv2 import numpy as np# 读图像 img = cv2.imread(F:\\learnOpenCV\\openCVLearning\\pictures\\chess.jpg)

应急日光灯 补光灯 太阳能路灯 升压LED电源驱动恒流IC

产品说明 AP9196 是一系列外围电路简洁的宽调光比升压调光 恒流驱动器&#xff0c;适用于 3-40V 输入电压范围的 LED 照明领域。 AP9196 采用我司专利算法&#xff0c;可以实现高精度的恒流 效果&#xff0c;输出电流恒流精度≤3&#xff05;&#xff0c;电压工作范围为 5-40V&…

重庆市人才系统注册流程

1、IE浏览器打开重庆市科技局官网首页(http://kjj.cq.gov.cn/) 2、选择“重庆市科技管理信息系统”—选择“科技资源共享”—板块—注册—选择“个人注册”—填写注册信息—注册 3、注册—选择“个人注册”—填写注册信息—注册—登录 4、选择“科技管理系统“ 5、选择“科技人…

Linux进程概念及其状态

文章目录 &#x1f347;1. 什么是进程&#x1f348;1.1 概念&#x1f348;1.2 理解进程 &#x1f34b;2. Linux的PCB&#x1f34e;3. 查看进程 & 杀死进程&#x1f352;4. 系统调用获取进程标识符&#x1f353;4.1 进程PID&#x1f353;4.2 父进程PPID &#x1f346;5. 系统…

MetInfo5.0文件包含漏洞

MetInfo历史版本与文件 环境在这里下载&#xff0c;使用phpstudy搭建 我们来看到这个index.php&#xff0c;如下图所示&#xff0c;其中定义了fmodule变量与module变量&#xff0c;其中require_once语句表示将某个文件引入当前文件&#xff0c;在这个代码中&#xff0c;通过r…

【JasperReports笔记06】JasperReport报表开发之常见的组件元素(Table、Subreport、Barcode等)

这篇文章&#xff0c;主要介绍JasperReport报表开发之常见的组件元素&#xff08;Table、Subreport、Barcode等&#xff09;。 目录 一、基础组件元素 1.1、StaticText 1.2、TextField 1.3、Image 1.4、Break分页 1.5、Rectangle矩形区域 1.6、Ellipse椭圆区域 1.7、Li…

基于MQTT协议的物联网关

随着工业领域的不断发展&#xff0c;数字化转型已经成为企业迈向未来的必由之路。在这个数字化浪潮中&#xff0c;HiWoo Box以其强大的功能和创新的设计&#xff0c;在工业物联网领域被越来越多的人所熟知。特别是其基于MQTT协议的物联网关能力&#xff0c;也为企业实现智能化数…

喷泉码浅谈

01、喷泉码简介 喷泉码&#xff08;Fountain Code&#xff09;是一种在无线通信、数据传输和网络编码领域中使用的错误纠正技术。它与传统的纠错码和编码方法有所不同&#xff0c;喷泉码被设计用于在不确定信道条件下的高效数据传输。传统的纠错码&#xff08;如海明码、RS码等…

无涯教程-Android - RadioButton函数

RadioButton有两种状态:选中或未选中,这允许用户从一组中选择一个选项。 Radio Button 示例 本示例将带您完成一些简单的步骤,以展示如何使用Linear Layout和RadioButton创建自己的Android应用程序。 以下是修改后的主要Activity文件 src/MainActivity.java 的内容。 packa…

【算法】函数渐近的界基础知识及定理

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

Spring依赖注入(DI)

目录 构造器注入 set注入 拓展注入 bean的作用域 Singleton Prototype Dependency Injection 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 . 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 . 构造器注入 具体实现&#xff1a;SpringIOC创建对象的…

电力行业浪涌保护器应用方案

电力行业是一个涉及到高压、大电流、复杂环境的领域&#xff0c;对于电气设备的安全和可靠性有着极高的要求。在电力行业中&#xff0c;浪涌是一种常见的电力质量问题&#xff0c;它指的是在电气系统中出现的瞬时过电压或过电流&#xff0c;可能由雷击、开关操作、短路故障等因…

算法通关村——解析堆的应用

在数组中找第K大的元素 LeetCode21 Medium 我们要找第 K 大的元素&#xff0c;如果我们找使用大堆的话那么就会造成这个堆到底需要多大的&#xff0c;而且哪一个是第 K 的的元素我们不知道是哪一个索引&#xff0c;我们更想要的结果就是根节点就是我们要找的值&#xff0c;所以…

java之SpringBoot基础、前后端项目、MyBatisPlus、MySQL、vue、elementUi

文章目录 前言JC-1.快速上手SpringBootJC-1-1.SpringBoot入门程序制作&#xff08;一&#xff09;JC-1-2.SpringBoot入门程序制作&#xff08;二&#xff09;JC-1-3.SpringBoot入门程序制作&#xff08;三&#xff09;JC-1-4.SpringBoot入门程序制作&#xff08;四&#xff09;…

cocosCreator 之 微信小游戏打包

版本&#xff1a; v3.8.0 环境&#xff1a; Mac 介绍 cocosCreator 支持将游戏发布到多个小游戏平台&#xff0c;并提供了打包等流程处理。 本篇文章主要讲述下微信小游戏的发布流程相关。更多内容参考官方文档&#xff1a; 发布到小游戏平台 微信小游戏的发布相关&#xff…

2023-8-31 Floyd求最短路

题目链接&#xff1a;Floyd求最短路 #include <iostream> #include <algorithm> #include <cstring>using namespace std;const int N 210, INF 1e9;int n, m, Q;int d[N][N];void floyd() {for(int k 1; k < n; k)for(int i 1; i < n; i)for(int …

并发编程的故事——并发之共享模型

并发之共享模型 文章目录 并发之共享模型一、多线程带来的共享问题二、解决方案三、方法中的synchronize四、变量的线程安全分析五、习题六、Monitor七、synchronize优化八、wait和notify九、sleep和wait十、park和unpark十一、重新理解线程状态十二、多把锁十三、ReentrantLoc…

瓜分双十一10亿红包设计:在线分享教程?

在如今激烈的市场竞争中&#xff0c;瓜分红包营销活动成为了各大企业争相使用的一种营销手段。这种活动不仅能够吸引用户的关注和参与&#xff0c;还能够提高用户的粘性和忠诚度。那么&#xff0c;如何自建瓜分红包营销活动呢&#xff1f;下面将为大家详细解析。 首先&#xff…