JavaSE篇:文件IO

news2024/10/4 8:06:42

一 认识文件

在硬盘这种持久化存储的I/O设备或其他存储介质中 ,当我们想要进行数据保存时,往往不是保存成⼀个整体,⽽是独⽴成⼀个个的单位进⾏保存,这个独⽴的单位就被抽象成⽂件的概念。就类似办公桌上的⼀份份真实的⽂件⼀般。
⽂件除了有数据内容之外,还有⼀部分信息,例如⽂件名、⽂件类型、⽂件⼤⼩等并不作为⽂件的数据⽽存在。

1.1 文件路径

文件路径就是描述一个文件在文件系统中的唯一标识,文件路径分为绝对路径和相对路径。绝对路径:从文件系统根目录开始定位某文件的具体位置的一个路线就是绝对路径。相对路径:以当前所在目录路径为基准,定位目标文件的路线。

1.2 文本文件与二进制文件

即使是普通⽂件,根据其保存数据的不同,也经常被分为不同的类型,我们⼀般简单的划分为⽂本文件和⼆进制⽂件。任何数据都以二进制形式存储在磁盘上,普通文件和二进制文件的主要区别在于它们的 内容格式。普通文件也要通常被如 UTF-8、ASCII编码集合(编码集合:一套普通字符映射二进制指令的规则)转换,是可以通过查表可以知道原数据内容,但是二进制文件存储在磁盘的内容是特殊的二进制数据,内容只能借助第三方工具。

二 Java中操作文件

Java操作对象分为:1)针对文件系统进行操作(创建目录,删除目录等),2)针对文件内容操作。Java 中通过 java.io.File 类来对⼀个⽂件(包括⽬录)进⾏抽象的描述。

2.1 File类概述

File类可认为是对文件(目录也是文件)的属性信息进行一些操作。

2.1.1 File类的构造函数

File类的构造函数
函数说明
File(File parent, String child)
根据⽗⽬录 + 孩⼦⽂件路径,创建⼀个新的 File 实例
File(String pathname)
根据⽂件路径创建⼀个新的 File 实例,路径可以是绝 对路径或者相对路径
File(String parent, String child)
根据⽗⽬录 + 孩⼦⽂件路径,创建⼀个新的 File 实 例,⽗⽬录⽤路径表⽰

最常用的是第二种,简单明了。

2.1.2 File类提供的方法 

修饰符及返回值类型
函数说明
String
getParent()
返回 File 对象的⽗⽬录⽂件路径
String
getName()
返回 FIle 对象的纯⽂件名称
String
getPath()
返回 File 对象的⽂件路径
String
getAbsolutePath()
返回 File 对象的绝对路径
boolean
exists()
判断 File 对象描述的⽂件是否真实 存在
boolean
isDirectory()
判断 File 对象代表的⽂件是否是⼀
个⽬录
boolean
isFile()
判断 File 对象代表的⽂件是否是⼀
个普通⽂件
String[]
list()
返回File对象代表的目录下所有的文件名
File[]
listFiles()
返回 File 对象代表的⽬录下的所有
⽂件,以 File 对象表⽰

import java.io.File;

public class dirio {
    public static void main(String[] args) {
        File file = new File("D:/test.txt");
        System.out.println(file.getName());
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.isFile());
        System.out.println(file.isDirectory());
    }
}

以上的函数并不是File类中的所有函数。这些方法都是JVM封装操作系统提供的API实现的。JVM是由C++实现的, 对于所有系统下,比如:Windows,Linux,都是统一的。都是使用这一套函数,因为JVM做了封装。程序员在使用时不用考虑兼容问题。

 三 文件内容的读写⸺数据流

Java中通过“流”这样的一组类进行对文件内容的操作,文件读写像流水一样。“流”分为两种,字节流和字符流。字节流是以字节为基本单位读写数据,有InputStream,OutputStream。字符流是以字符为基本单位读写数据,有Reader,Writer。

3.1 InputStreamのFileInputStream读取数据

 查看InputStream可知,InputStream类被abstract修饰,证明这是一个抽象类,想使用它要自己定义类重写抽象方法。标准库中,已经实现了InputStream的的子类,不仅仅有对磁盘文件的读取的子类,也有从网卡读取的子类(PipedInputStream)等等。标准库实现对磁盘文件读取的子类是FileInputStream。

使用方法很简单,1)调用构造函数创建FileInputStream对象 2)调用FileInputStream类实现的函数完成读取操作

FileInputStream的构造函数有两种。

 FileInputStream会抛受查异常(编译时异常)FileNotFoundException, FileNotFoundException 是 Java 中的一个异常,表示试图打开一个不存在的文件或路径。它是 IOException的子类。IOException 是 Java 中的一个异常类,表示在进行输入输出操作失败或被中断。它是所有输入输出异常的父类。

接下来调用FileInputStream的read方法,即可读取对应文件的数据。read方法有三种格式。

3.1.1 read无参版本

1)第一种无参版本,每次只读一个字节,读取到的内容通过返回值返回,如果读取不到返回-1,返回值不用byte而是用int,是因为byte范围是从-128-127,如果读取失败,无法通过返回值告知。所以采用了int。

import java.io.*;

public class dirio {
    public static void main(String[] args) throws IOException {
        File file = new File("D:/test.txt");

        FileInputStream fileInputStream = new FileInputStream("D:/test.txt");
        while (true) {
            int res = fileInputStream.read();
            if (res == -1)
                break;
            System.out.printf("%c", res);
        }
    }
}

 

为什么不用short而是用int,使用short不是可以省下2个字节吗?

short和float是上个世纪80,90时代使用的,那时候还是采用的16位CPU,内存紧张。如今硬件设备发展迅速,已经不在乎2个字节的消耗,而且就算使用short,如今使用的32位CPU也会将short整形提升为int。float精度太低,容易造成误差,所以更不用了。

3.1.2 read单参数版本

read(byte[ ]),byte[ ]是一个输出型参数。对,就是C++中的那个输出型参数,这种方式在C++中是很常用的,但是在Java中是不常用的。读取到的结果回被存储在传进去的byte数组中。返回值是实际读取到了多少个字节。

import java.io.*;

public class dirio {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("D:/test.txt")) {
            byte[] buf = new byte[1024];
            int len = 0;
            while(true) {
                len = is.read(buf);
                if (len == -1) {
                    // 代表⽂件已经全部读完
                    break;
                }
                for (int i = 0; i < len; i++) {
                    System.out.printf("%c", buf[i]);
                }
            }
        }
    }
}

3.1.3 read三参数版本

read(byte[ ],int off,int len) 从off下标开始读取len个长度字节存储在byte数组中。

3.2 关闭文件

使用FileInputStream读取文件,在操作系统中,其实是会在进程PCB的文件描述符表中的数组中占一个位置,这个数组的长度是有一定限度的,如果这个数组被占满了再打开文件就放不下了,这个进程就崩溃了,服务器是7×24小时运行的,所以不能崩,要及时手动关闭打开的文件,避免文件资源泄露。在Linux上,ulimit -n可以查看这个数组的大小。如果怕忘记了,可以借助try语句。try with resources。在try后面跟一个圆括号,资源会在 try 块结束后自动关闭,减少了代码中的冗余。

import java.io.*;

public class dirio {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("D:/test.txt")) {
            ,,,,,,
        }
    }
}

3.3 OutputStreamのFileOutputStream写入数据

OutputStream 同样只是⼀个抽象类,要使⽤还需要具体的实现类。我们现在还是只关⼼写⼊⽂件
中,所以使⽤ FileOutputStream。OutputStream和FileOutputStream的关系和InputStream和FileInputStream的关系一样。构造方式也是一样的。
FileOutputStream的write版本也有三个,

注意:在构造时候,默认是清空内容再写入,如果想追加,则构造时候,加一个true。

3.3.1 write无参版本

一次写入一个字节,它的参数类型是int。在 Java 中,int的范围是 -2,147,483,648 到 2,147,483,647,而字节的范围是 0 到 255。将一个字节(0-255)转换为int,可以用int 表示这个字节的值,方便地进行位运算。如果直接使用 byte 类型作为参数,可能会引起一些混淆,因为 byte 是有符号的(-128 到 127)。通过使用 int,你可以在方法内部更容易地处理和转换数据。

import java.io.*;
public class Main {
 public static void main(String[] args) throws IOException {
     try (OutputStream os = new FileOutputStream("output.txt")) {
         os.write('H');
         os.write('e');
         os.write('l');
         os.write('l');
         os.write('o'); 
         }
    }
}

3.3.2 write单参数byte数组

import java.io.*;

public class dirio {
    public static void main(String[] args) throws IOException {

        try(FileOutputStream os = new FileOutputStream("D:/test.txt",true)) {
            byte[] b = new byte[] { 'G', 'o', 'o', 'd' };
            os.write(b);
        }
    }
}

3.3.3 write三参数版本

import java.io.*;

public class dirio {
    public static void main(String[] args) throws IOException {

        try (OutputStream os = new FileOutputStream("D:/test.txt")) {
            byte[] b = new byte[] {'G','o', 'o','d','B','a'};
            os.write(b, 0, 4);
        }
    }
}

三 总结

文件IO类还有很多,使用方法大同小异。基本都是有一个父类,再根据不同的场景封装不同的系统调用。对于文件IO基本就有三步1)打开文件(构造)  2)读写  3)关闭文件

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

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

相关文章

疾风气象大模型如何预测气象数据,预测数据怎么获得

随着科技的快速发展&#xff0c;人工智能和大数据技术逐渐渗透到各个领域&#xff0c;气象预测也不例外。过去&#xff0c;气象预测主要依赖于物理模型&#xff0c;结合大气、海洋、陆地等系统的观测数据&#xff0c;通过复杂的数值计算来推测未来天气。而如今&#xff0c;大模…

八、跳跃、闪避

一、人物跳跃功能 1、动画 设置一个bool值 条件设置为true 2、逻辑 实现跳跃&#xff0c;一定有IsGround&#xff1b;判断是否为地面&#xff0c;进行跳跃功能 写一个跳跃和一个条约结束方法 跳跃设置为false&#xff0c;结束设置为true 3、代码 public void Jump() {if…

Ray_Tracing_In_One_Weekend下

1Lambertian漫反射材质 一个物体的材质&#xff0c;可以分成两部分来看&#xff0c;因为物体没有绝对光滑和绝对粗糙 漫反射&#xff1a;由于物体粗糙&#xff0c;那么对于微小平面&#xff0c;光线会向四周反射&#xff0c;光源的一部分光线传回人眼 镜面反射&#xff1a;假…

C++ 类和对象的初步介绍

文章目录 1.面向过程和面向对象的初步认识2.类的引入3.类的定义4. 类的访问限定符及封装4.1 访问限定符4.2 封装 5.类的作用域6.类的实例化 1.面向过程和面向对象的初步认识 C语言是面向过程的&#xff0c;关注的过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用…

OpenCV Canny()函数

OpenCV Canny()函数被用来检测图像物体的边缘。其算法原理如下&#xff1a; 高斯滤波&#xff1a;使用高斯滤波器平滑图像以减少噪声。高斯滤波器是一种线性滤波器&#xff0c;可以消除图像中的高频噪声&#xff0c;同时保留边缘信息。计算梯度强度和方向&#xff1a;使用Sobe…

教资备考--高中数学(仅为高中数学梳理)

按照高中学习数学梳理的方案进行整理

爬虫——同步与异步加载

一、同步加载 同步模式--阻塞模式&#xff08;就是会阻止你浏览器的一个后续加载&#xff09;停止了后续的解析 因此停止了后续的文件加载&#xff08;图像&#xff09; 比如hifini音乐网站 二、异步加载 异步加载--xhr(重点) 比如腾讯新闻&#xff0c;腾讯招聘等 三、同…

组合框QGroupBox设置checked属性

我们可以给组合框设置checked属性 //获取和设置checked属性是否开启 bool isCheckable() const void setCheckable(bool checkable)//获取和设置选中还是非选中 bool isChecked() const void setChecked(bool checked)效果如下&#xff1a; 如果checked属性使能之后&#xff0…

Open3D实现点云数据的序列化与网络传输

转载自个人博客&#xff1a;Open3D实现点云数据的序列化与网络传输 在处理点云数据的时候&#xff0c;有时候需要实现点云数据的远程传输。当然可以利用传输文件的方法直接把点云数据序列化成数据流进行传输&#xff0c;但Open3D源码在实现RPC功能时就提供了一套序列化及传输的…

用langchain+streamlit应用RAG实现个人知识库助手搭建

RAG原理概述 RAG&#xff08;Retrieval-Augmented Generation&#xff09; 是一种结合了信息检索和生成式人工智能技术的模型架构&#xff0c;旨在让模型生成更有根据和更准确的回答。通俗来讲&#xff0c;它让模型不只是凭借自己的“记忆”&#xff08;预训练数据&#xff09…

Java中的依赖注入(Dependency Injection, DI)详解

Java中的依赖注入&#xff08;Dependency Injection, DI&#xff09;是软件工程中的一种重要设计模式。它有助于提高系统的可测试性、可维护性和灵活性。通过依赖注入&#xff0c;组件不再负责创建它们所需的对象&#xff0c;而是通过外部的设置来提供这些对象。这种方式也与控…

无人机+无人车+机器狗:综合管控系统技术详解

无人机、无人车、机器狗的综合管控系统技术是一个集成了多种先进技术和设备的复杂系统&#xff0c;旨在实现高效、精准、协同的作业与管理。以下是对该系统技术的详细解析&#xff1a; 一、系统概述 综合管控系统通过集成无人机、无人车和机器狗等智能设备&#xff0c;结合物…

OSDU轻量化单机部署

首先更新系统 sudo apt update sudo apt upgrade -y安装docker sudo apt install -y docker.io sudo systemctl start docker sudo systemctl enable docker安装minikube curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 …

vmware Workstation16设置批量虚拟机开机自启 vmAutoStart

文章目录 前言解压压缩包一、使用步骤1.获取虚拟机所在目录2.获取vmware所在目录3.测试启动4.开机自启 二、gitee总结 前言 vmware workstation16不支持虚拟机开机自启&#xff0c;通常的办法是写脚本&#xff0c;但是有个问题就是不能启动多台虚拟机&#xff0c;因为有时候会…

Python | Leetcode Python题解之第455题分发饼干

题目&#xff1a; 题解&#xff1a; class Solution:def findContentChildren(self, g: List[int], s: List[int]) -> int:g.sort()s.sort()m, n len(g), len(s)i j count 0while i < m and j < n:while j < n and g[i] > s[j]:j 1if j < n:count 1i …

Spring框架使用Api接口实现AOP的切面编程、两种方式的程序示例以及Java各数据类型及基本数据类型的默认值/最大值/最小值列表

一、Spring框架使用Api接口-继承类实现AOP的切面编程示例 要使用Spring框架AOP&#xff0c;除了要导入spring框架包外&#xff0c;还需要导入一个织入的包org.aspectj&#xff0c;具体maven依赖如下&#xff1a; <dependency><groupId>org.springframework</gr…

JAVA-异常(通俗易懂)

目录 一、异常的概念 1.算术异常 2.数组越界异常 3.空指针异常 二、异常体系结构 三、异常的分类 1. 编译时异常 2. 运行时异常 四、异常处理 1.防御式编程 2.异常的抛出 3.异常的捕获 4.try-catch捕获并处理 5.finally 五、异常的处理流程 六. 自定义异常类…

ade20k 街景图像【数据集】及其【论文出处】ADE20K数据集 超过25000张图像的语义分割数据集

ade20k 街景图像【数据集】及其【论文出处】ADE20K数据集介绍 是一个包含超过25000张图像的语义分割数据集&#xff0c;这些图像被密集注释&#xff0c;覆盖室内和室外场景。 它由MIT发布&#xff0c;包含100个事物类别和50个物质类别&#xff0c; 用于训练和验证的图像数量分别…

(16)MATLAB仿真Nakagami-m分布1

文章目录 前言一、Nakagami分布二、MATLAB建模代码三、仿真结果画图四、总结 前言 Nakagami衰落模型最初是由于该模型与短波电离层传播的经验结果相匹配而提出的。它还用于仿真来自多个干扰源的情况&#xff0c;因为多个独立且同分布&#xff08;i.i.d&#xff09;的瑞利分布随…

线程池的实现和讲解:解决多线程并发服务器创建销毁线程消耗过大的问题

1.前言 多进程/线程并发服务器、多路I/O转接服务器的简单实现-CSDN博客 原先的多线程并发服务器&#xff0c;有多少个客户端连接服务器就有多少个线程&#xff0c;CPU需要在多个线程之间来回切换处理客户端的请求&#xff0c;系统消耗比较大(每次创建和消耗线程在操作系统内部…