文件操作IO

文件操作IO

  • .
  • 认识文件
  • 树型结构组织 和 目录
  • 文件路径(Path)
  • 其他知识
  • Java 中操作文件
    • 构造方法
    • 方法
  • 创建文件
  • 删除文件
  • 创建目录
  • 重命名
  • 文件内容的读写 —— 数据流
    • Reader/Writer(字符流)
    • InputStream/OutputStreadm(字节流)
      • scanner
  • 例题
    • 1.扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要
    • 2.进行普通文件的复制

.

在这里插入图片描述

认识文件

我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公桌上的一份份真实的文件一般
文件除了有数据内容之外,还有一部分信息,例如文件名、文件类型、文件大小等并不作为文件的数据而存在,我们把这部分信息可以视为文件的元信息

树型结构组织 和 目录

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

文件路径(Path)

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

C:\Program Files (x86)\Microsoft\Temp\EU5153.tmp

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

.\表示当前目录
. .\表示上级目录

这里的分隔符可以是,也可以是/,但是为了避免\与字符组合i形成转义字符,需要用\来转义一下其中的一个,

其他知识

即使是普通文件,根据其保存数据的不同,也经常被分为不同的类型,我们一般简单的划分为文本文件和二进制文件,分别指代保存被字符集编码的文本和按照标准格式保存的非被字符集编码过的文件。Windows 操作系统上,会按照文件名中的后缀来确定文件类型以及该类型文件的默认打开程序。但这个习俗并不是通用的,在 OSX、Unix、Linux 等操作系统上,就没有这样的习惯,一般不对文件类型做如
此精确地分类。
文件由于被操作系统进行了管理,所以根据不同的用户,会赋予用户不同的对待该文件的权限,一般地可以认为有可读、可写、可执行权限
Windows 操作系统上,还有一类文件比较特殊,就是平时我们看到的快捷方式(shortcut),这种文件只是对真实文件的一种引用而已。其他操作系统上也有类似的概念,例如,软链接(soft link)等。
最后,很多操作系统为了实现接口的统一性,将所有的 I/O 设备都抽象成了文件的概念,使用这一理念最为知名的就是 Unix、Linux 操作系统 —— 万物皆文件
技巧:
将文件拖入记事本,能看懂就是文本文件,看不懂就是二进制文件

Java 中操作文件

在这里插入图片描述
站在CPU的角度,将数据从内存读到硬盘中,是输出,从硬盘读取到内存中,是输入
本节内容中,我们主要涉及文件的元信息、路径的操作,暂时不涉及关于文件中内容的读写操作。
Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不代表真实存在该文件

构造方法

在这里插入图片描述

方法

在这里插入图片描述

package Thread;

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

public class demo1 {
    public static void main(String[] args) throws IOException {
        File file = new File("d:/text.txt");
        System.out.println(file.getParent());
        System.out.println(file.getName());
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getCanonicalPath());
    }
}

在这里插入图片描述

package Thread;

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

public class demo1 {
    public static void main(String[] args) throws IOException {
        File file = new File("./text.txt");
        System.out.println(file.getParent());
        System.out.println(file.getName());
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getCanonicalPath());
    }
}

在这里插入图片描述
这里的getAbsolutePath会将工作路径与设定的当前路径相结合,工作路径就是程序所在的路径,getCanonicalPath则是会将getAbsolutePath合成的目录进行整理优化,去掉冗余的部分

创建文件

package Thread;

import java.io.File;

public class demo2 {
    public static void main(String[] args) {
        File file = new File("./text.txt");
        System.out.println(file.exists());
        System.out.println(file.isFile());
        System.out.println(file.isAbsolute());
    }
}

在这里插入图片描述
在这里插入图片描述

package Thread;

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

public class demo2 {
    public static void main(String[] args) throws IOException {
        File file = new File("./text.txt");
        file.createNewFile();
        System.out.println(file.exists());
        System.out.println(file.isFile());
        System.out.println(file.isAbsolute());
    }
}

在这里插入图片描述
在这里插入图片描述
可以看出,第一段代码,由于并没有创建一个text.txt的文件,所以打印都是false,而第二个代码,从目录中可以看到,已经将text.txt创建出来了,由于是newfile创建出来的,所以打印结果是true true false

删除文件

package Thread;

import java.io.File;

public class demo3 {
    public static void main(String[] args) throws InterruptedException {
        File file = new File("./text.txt");
//        file.delete();
        file.deleteOnExit();
        Thread.sleep(5000);
    }
}

在这里插入图片描述
上述代码,delate和deleteOnExit都可以将文件删除,不同的是,deleteOnExit是需要等到程序结束后才会将文件删除

创建目录

package Thread;

import java.io.File;
import java.util.logging.FileHandler;

public class demo4 {
    public static void main(String[] args) {
        File file = new File("./textDir");
        //mkdir一次只能创建一个目录,mkdirs一次可以创建很多个目录
        file.mkdir();
//        file.mkdirs();
    }
}

在这里插入图片描述

package Thread;

import java.io.File;
import java.util.logging.FileHandler;

public class demo4 {
    public static void main(String[] args) {
        File file = new File("./textDir/111/222/333");
        //mkdir一次只能创建一个目录,mkdirs一次可以创建很多个目录
//        file.mkdir();
        file.mkdirs();
    }
}

在这里插入图片描述

重命名

package Thread;

import java.io.File;

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

我们先将file文件给创建出来,再利用rename将file文件名改为filename
在这里插入图片描述
在这里插入图片描述
rename还可以起到文件移动的作用

package Thread;

import java.io.File;

public class demo5 {
    public static void main(String[] args) {
        File file = new File("./test.txt");
        File file2 = new File("./src/test2.txt");
        file.renameTo(file2);
    }
}

在这里插入图片描述
此时文件test.txt已经从src目录外面给挪到src里面去了

文件内容的读写 —— 数据流

文件这里的内容本质是来自于硬盘,硬盘又是操作系统管理的,使用某个编程语言操作文件,本质上都是需要调用系统的api,
虽然不同的编程语言,操作文件的api有所差别,但是,基本步骤都是一样的,
文件内容的操作核心步骤,有四个
1.打开文件
2.读文件
3.写文件
4.关闭文件

javaIO流是一个比较庞大的体系,涉及到非常多的类,这些不同类,都有各自不同的特性,但是总的来说,使用方法都是类似的,
1.构造方法,打开文件
2.close方法,关闭文件,
3.如果衍生自InputStream或者Read,就可以使用read方法来读数据
4.如果衍生自OutputStreadm或者Writer,就可以使用writer方法来读数据
接下来,我们来举个例

Reader/Writer(字符流)

后续的一些操作字符的类都是衍生自这两个类,是操作字符为单位(文本文件)
先提前再d盘创建一个文件,写入一些数据后,我们尝试将利用程序其打开并读取

在这里插入图片描述
在这里插入图片描述

package Thread;

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

//Read的使用
public class demo6 {
    public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("D:/Data/test.txt");
        try {

        }finally {
            reader.close();
        }
    }
}

这里的close非常重要,是用来释放不必要的资源的,这是因为,让一个进程打开一个文件,是需要从系统中申请一定的资源的(占用进程的pcb里的文件描述符表中的资源,这里的表是一个顺序表,长度有限,不会自动扩容)
,如果不释放,就会出现"文件资源泄露"这个很严重的问题,一旦一直打开文件,而又不去关闭不用的文件,文件描述符表就会被占满,后续就无法继续打开新的文件了
上述的finally虽然也能够解决问题,但是不够优雅,我们可以使用try with resources

package Thread;

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

//Read的使用
public class demo6 {
    public static void main(String[] args) throws IOException {
        try(Reader reader = new FileReader("D:/Data/test.txt")){
            //只要try代码块执行完了,就会自动调用到close
            //括号里面还可以创建多个对象,用;隔开
        }

    }
}

文件流中的任意对象,都可以按照上述的讨论来进行close

package File;

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

public class demo1 {
    public static void main(String[] args) {
        try(Reader reader = new FileReader("d:/data/test.txt")) {
//            reader.read();//从文件中读取一个字节,返回类型是一个两个字节的Integer
            while (true){
                char []buf = new char[1024];
                int n = reader.read(buf);//通过read,就会把本来是一个空的数组,填充上内容,此处的参数就是一个输出型参数
                //这里的返回值是一个整型变量,表示实际读取到的字符个数,如果文件访问到末尾了,比如eof,就会返回一个-1
                if (n==-1){
                    break;
                }
                for (int i =0;i<n;i++){
                    System.out.print(buf[i]+" ");
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

在这里插入图片描述
还有这个方法,主要用在从多个文件中读取不同位置的数据.
写文件: 输出,使用方法和输入非常相似,关键操作是write,write之前要打开文件,用完了也需要关闭文件
输出流对象(无论是字节流还是字符流),都会在打开文件之后,清空文件内容
Write这个方法可以直接传输一个字符串,这是非常方便的

package File;

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

public class demo4 {
    public static void main(String[] args) throws IOException {
        try(Writer writer = new FileWriter("d:/data/test.txt")){
            writer.write("hello java");
        }
    }
}

在这里插入图片描述
若想把新的内容加在之前的内容后面,就可以采用追加的方式,也就是在打开文件的时候,添加一个参数

package File;

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

public class demo4 {
    public static void main(String[] args) throws IOException {
        try(Writer writer = new FileWriter("d:/data/test.txt",true)){
            writer.write("hello java2");
        }
    }
}

在这里插入图片描述

InputStream/OutputStreadm(字节流)

后续的一些操作字节的类都是衍生自这两个类,是操作字节为单位(二进制文件)
InputStream是字节流,用法和Reader非常相似,文本文件也可以用字节流打开,只不过此时读到的每个字节,就不是完整的字符了

package File;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class demo2 {
    public static void main(String[] args) throws IOException {
        try(InputStream inputStream = new FileInputStream("d:/data/test.txt")){
//            inputStream.read();//一次读一个字节,虽然返回值是int,但是实际上只有0-255,也就是一个字节的大小
           while (true){
               byte []buf = new byte[1024];
               int n = inputStream.read(buf);//一次读若干字节,尝试填满数组
               if (n==-1){
                   break;
               }
               for (int i =0;i<n;i++){
                   System.out.printf(" %x ", buf[i]);
               }
           }

        }
    }
}

在这里插入图片描述

在这里插入图片描述
一次读取若干字节,填满一部分

scanner

public class demo3 {
    public static void main(String[] args) throws IOException {
        try(InputStream inputStream = new FileInputStream("d:/data/test.txt")){
            Scanner scanner = new Scanner(inputStream);
            String s = scanner.next();
            System.out.println(s);
        }
    }
}

在这里插入图片描述
以前学习的Scanner操作,在这里完全适用,但是,要注意,Scanner只是用来读取文本文件的,不适合读取二进制文件
OutputStream使用方式和Write完全一样,只是不能使用字符串参数,只能按照字节,或者字节数来写入
Scanner搭配inputStream 达到简化代码的效果,
PrintWriter搭配OutputStream,提供了一系列的方法,printf,println

例题

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

删除该文件

package File;

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

//扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
//        注意:我们现在的方案性能较差,所以尽量不要在太复杂的目录下或者大文件下实验
public class demo5 {
    public static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        System.out.println("请输入想要查找的根目录");
        File dir = new File(scanner.next());
        System.out.println("请输入想要查找的文件");
        File file = new File(scanner.next());
        if (!dir.isDirectory())
            return;
        ScanDir(dir,file);

    }
    public static void ScanDir(File dir , File file) throws IOException {
        File [] files = dir.listFiles();
        if (files.length==0||files==null)
            return;
        for (File file1:files) {
            System.out.println(file1.getCanonicalPath());
            if (file.isDirectory()){
                ScanDir(file1,file);
            } else {
                DealFile(file1,file);
            }
        }
    }
    public static void DealFile(File dir , File file){
        if (dir!=file)
            return;
        System.out.println("是否要删除该文件(Y/N)");
        String s = scanner.next();
        if (s=="Y"||s=="N")
            file.delete();
    }

}

2.进行普通文件的复制

package File;

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

//进行普通文件的复制
public class DEMO6 {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入想要复制的文件");
        String file1 = scanner.next();
        File srcFile = new File(file1);
        if (!srcFile.isFile())
        {
            return;
        }
        System.out.println("请输入文件复制的目的地");
        String file2 = scanner.next();
        File destFile = new File(file2);
        if (!destFile.getParentFile().isDirectory())
            return;

        try(InputStream inputStream = new FileInputStream(srcFile);
            OutputStream outputStream = new FileOutputStream(destFile)){
            byte[]buf = new byte[1024];
            while (true){
                int n = inputStream.read(buf);
                if (n==-1)
                    break;
                outputStream.write(buf,0,n);
            }
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC 学习(一)之 SpringMVC 介绍

目录 1 MVC 介绍 2 SpringMVC 介绍 2.1 SpringMVC 特点 2.2 SpringMVC 的核心组件 2.3 SpringMVC 执行流程 3 参考文档 1 MVC 介绍 MVC (Model View Controller) 是一种设计思想&#xff0c;它将应用程序分为三大组件&#xff1a;模型 (Model)、视图 (View)、控制器 (Con…

素数筛法详解:埃氏筛和欧拉筛

主要讲解怎么判断一个数字是否是素数&#xff1a; 埃式筛 学习埃氏筛之前&#xff0c;我们先看一下暴力筛法&#xff0c;即对每个数都用试除法判断其是不是质数&#xff1a; 暴力筛法&#xff1a; # include <stdio.h>int main() {int st[N]; // 初始化为0&#xff0…

rider 缺少iisexpress

File C:/Program Files (x86)/IIS Express/iisexpress.exe doesn’t exist iisexpress下载 64位系统只能安装64位&#xff0c;32位系统安装32位 安装完成之后就有了

MacBook的nginx出现13: Permission denied 的问题分析和解决办法

同样的项目代码&#xff0c;电脑从Windows更换到了MacBook&#xff0c;发现网站的样式都没有了&#xff0c;直接访问CSS文件 http://crm.ms-test.cc/toolstatic/css/bootstrap.min.css 发现无法访问。查看Nginx错误日志&#xff1a; 说明是nginx没有权限访问这个CSS文件&#…

NDK的log.h使用__android_log_print报错app:buildCMakeDebug[x86_64]

org.gradle.api.tasks.TaskExecutionException: Execution failed for task :app:buildCMakeDebug[x86_64] 重点是 Execution failed for task :app:buildCMakeDebug[x86_64]. 我的代码&#xff1a; #include <android/log.h> #define LOG_TAG "MyJNI" #d…

20240113----重返学习-`nginx/conf/nginx.conf`的https证书配置说明

20240113----重返学习-nginx/conf/nginx.conf的https证书配置说明 文件说明 不同域名的多虚拟主机配置 server {listen 443 ssl;#在443端口上监听SSL/TLS流量;server_name localhost;#指定服务器名称&#xff0c;应该与域名匹配;ssl_certificate fangchaoduan.com.pem;#指定SS…

Linux之ACL权限管理

文章目录 1.ACL权限介绍二、操作步骤1. 添加测试目录、用户、组&#xff0c;并将用户添加到组2. 修改目录的所有者和所属组3. 设定权限4. 为临时用户分配权限5. 验证acl权限6. 控制组的acl权限 1.ACL权限介绍 每个项目成员有一个自己的项目目录&#xff0c;对自己的目录有完全…

DSL Query基本语法

DSL Query基本语法 查询的基本语法如下&#xff1a; GET /indexName/_search {"query":{"查询类型":{"查询条件":"条件值"}} }查询所有 GET /indexName/_search {"query":{"match_all":{}} }match查询&#xf…

【高德地图】Android高德地图绘制标记点Marker

&#x1f4d6;第4章 Android高德地图绘制标记点Marker ✅绘制默认 Marker✅绘制多个Marker✅绘制自定义 Marker✅Marker点击事件✅Marker动画效果✅Marker拖拽事件✅绘制默认 Infowindow&#x1f6a9;隐藏InfoWindow 弹框 ✅绘制自定义 InfoWindow&#x1f6a9;实现 InfoWindow…

MyBatis之Mapper.xml文件中parameterType,resultType,resultMap的用法

MyBatis之自定义数据类型转换器 前言1.parameterType2.resultType3.resultMap实例代码总结 前言 今天我们来学习Mapper.xml&#xff08;编写SQL的&#xff09;文件中&#xff0c;增删改查标签中&#xff0c;使用parameterType属性指定传递参数类型&#xff0c;resultType属性指…

人工智能_CPU微调ChatGLM大模型_使用P-Tuning v2进行大模型微调_007_微调_002---人工智能工作笔记0102

这里我们先试着训练一下,我们用官方提供的训练数据进行训练. 也没有说使用CPU可以进行微调,但是我们先执行一下试试: https://www.heywhale.com/mw/project/6436d82948f7da1fee2be59e 可以看到说INT4量化级别最低需要7GB显存可以启动微调,但是 并没有说CPU可以进行微调.我们…

日本极致产品力 | 如何在三得利等巨头压制下,打造出1秒麦1瓶的矿泉水品牌?

《极致产品力》日本深度研学,可以帮企业找产品、找方向、找方法,在日本终端市场考察中洞悉热销产品背后的成功逻辑,了解最新最前沿的产品趋势和机会。结合日本消费趋势中国转化的众多经验从品牌、包装、卖点、技术和生产工艺等多方面寻找中国市场的解决方案。 Nomusilica(又称诺…

springboot214基于springboot的多媒体素材库的开发与应用

多媒体素材库的设计与实现 摘要 近年来&#xff0c;信息化管理行业的不断兴起&#xff0c;使得人们的日常生活越来越离不开计算机和互联网技术。首先&#xff0c;根据收集到的用户需求分析&#xff0c;对设计系统有一个初步的认识与了解&#xff0c;确定多媒体素材库的总体功…

Unity之PUN2插件实现多人联机射击游戏

目录 &#x1f4d6;一、准备工作 &#x1f4fa;二、UI界面处理 &#x1f4f1;2.1 登录UI并连接PUN2服务器 &#x1f4f1;2.2 游戏大厅界面UI &#x1f4f1;2.3 创建房间UI &#x1f4f1;2.4 进入房间UI &#x1f4f1;2.5 玩家准备状态 &#x1f4f1;2.6 加载战斗场景…

PBM模型学习

本专栏着重讲解PBM学习所得&#xff0c;学习笔记、心得&#xff0c;并附有视频素材资料&#xff0c;视频详细目录如下&#xff1a; PBM相关参数解释1 PBM相关参数解释2 PBM相关案例实践1 PBM相关案例实践2 PBM相关案例实践2 PBM相关案例实践3 PBM多相流中次相界面设置1 PBM多相…

高级语言期末2012级B卷

1.编写函数&#xff0c;输出任意正整数n的位数&#xff08;n默认为存储十进制的整形变量&#xff09; 例如&#xff1a;正整数13&#xff0c;则输出2,&#xff1b;正整数3088&#xff0c;则输出4 #include <stdio.h>int func(int n) {int count0;while(n>0) {n/10;co…

区块链与Solidity详细介绍及基本语法使用

一、区块链简介 区块链是一种分布式数据库技术&#xff0c;它以块的形式存储数据&#xff0c;并通过加密算法确保数据的安全性。每个块包含一系列交易&#xff0c;并通过哈希值与前一个块相连接&#xff0c;形成一个链式结构。这种结构使得数据难以被篡改&#xff0c;因为任何对…

js设计模式:组合模式

作用: 可以用来将数据组合成树形的数据,可以像操作单独的对象一样去操作整个树形结构 树是相对复杂的数据,使用组合模式去封装树形的组件,是很重要的,可以对外暴露很多树的操作方法 示例: //一个树型的对象数据class Organ {constructor(label, value, parentName) {this.la…

【MySQL】数据库概述

目录 一、为什么使用数据库&#xff1f; 二、数据库与数据库管理系统 2.1 相关概念 2.2 两者关系 三、 MySQL介绍 四、 RDBMS和非RDBMS 4.1 关系型数据库&#xff08;RDBMS&#xff09; 4.2 非关系型数据库&#xff08;非RDBMS&#xff09; 五、关系型数据库设计规则 …

OCPP 1.6 接入实现文档

一、简介 OCPP&#xff08;Open Charge Point Protocol&#xff09;是一个开放的通信协议&#xff0c;用于充电站&#xff08;Charge Point&#xff09;与中央系统&#xff08;Central System&#xff0c;如充电站管理系统或服务提供商平台&#xff09;之间的通讯。本篇文档将…
最新文章