JAVAEE——文件IO

文章目录

  • 文件的概念
    • 什么是文件?
    • 树型结构组织 和 目录
    • 文件路径
      • 相对路径
      • 绝对路径
    • 文件的分类
    • 文件的权限
  • 文件读写IO API
    • 字符流操作API
  • 警告
    • 字节流操作API
      • InputStream
      • OutputStream

文件的概念

什么是文件?

我们先来理解一下什么是文件,那么想要知道什么是文件的话,我们首先要知道文件是干嘛的,文件其实就是用来保存数据的,我们知道我们电脑产生的数据是保存在了硬盘里的,可是那么多的数据如果我们不进行分类保管的话就会导致所有的数据乱作一团,因此就有了文件,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公桌上的一份份真实的文件一般,那么我们创建了一个文件但是不往里面写东西那么这个文件有内存吗?也就是说创建一个空的文件,那么这个文件真的就是不占内存吗?显然这个答案是不对的,即使这个文件什么东西也没写他也不可能就一些内存没占,这是为什么呢?
因为一个文件需要储存的其实不止他所包含的数据还有他自己的一些属性比如说这个文件的名称还有这个文件的位置这些属性信息同样也是需要储存的。既然需要储存那就一定占了内存。

树型结构组织 和 目录

前面说了文件里面用来保存了文字数字等内容,可是一堆的文件放在那里也不好看啊,怎么办呢?这时候聪明的人类就想到了一个好点子那就是像文件保存数据一样创造一种类型让他能够保存文件,这个类型就是文件夹。当然了我们应该叫做目录。
这些目录是按照什么进行排列的呢?当然是树形了。我们可以看一下下面这个图
在这里插入图片描述
我们可以看到上面的目录和文件的关系其实就是像棵树一样也就是多叉树。

文件路径

既然文件的一个存放是一个多叉树的类型,那么我们应当如何定位一个文件呢?那么这时候就需要文件路径了。
那么文件路径又分为相对路径和绝对路径

相对路径

从任意节点出发到达目标节点的路径称为相对路径。

绝对路径

从根节点出发到达目的节点的方式成为绝对路径。

文件的分类

那么文件分为哪几类呢?文件分为二进制文件和文本文件,那么什么是二进制文件,什么是文本文件呢?二进制文件是指文件中的内容是二进制的形式,这些文件我们人是看不懂的,二进制文件常见的是以bin为结尾,而文本文件常见的是以txt形式为结尾。

文件的权限

关于文件的权限其实windows上体验的其实不是很明显,因为windows中自带的就是管理员权限,但是Linux中感觉就很明显了,那么文件权限的意义是什么呢?文件由于被操作系统进行了管理,所以根据不同的用户,会赋予用户不同的对待该文件的权限,一般地可以认为有可读、可写、可执行权限。
Windows 操作系统上,还有一类文件比较特殊,就是平时我们看到的快捷方式(shortcut),这种文
件只是对真实文件的一种引用而已。其他操作系统上也有类似的概念,例如,软链接(soft link)等。

文件读写IO API

关于文件的操作可以分为两大类,如下图
在这里插入图片描述
那么什么是字符流什么又是字节流呢?他们两个区分其实很简单,字符流操作中的基本单位是字符,字节流操作的基本单位是字节。
那么我们来分别进行操作。

字符流操作API

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

public class test_byte {
    public static void main(String[] args) throws IOException {
        Reader reader=new FileReader("d:/test.txt");
        char[] arr=new char[1024];
        reader.read(arr);
        System.out.println(arr);
    }
}

首先我们先来看一下这个代码假如说我的d盘中没有test.txt那么这个代码可以执行吗?答案是可以的 但是会抛出异常
在这里插入图片描述
这里我们可以看到这里的异常说明系统找不到指定文件那么我们将其创建出来。然后我们向里面写一些东西来进行测试
在这里插入图片描述
这里我们发现我们输出的东西很奇怪因为他输出了我们写的内容之后有输出了一个很奇怪的字符这是为什么呢?因为我们刚刚对这个字符串类型初始化的是1024个字节,但是这里面的内容很明显没有1024这时候还有一些没被初始化的地方就变成了现在这样了。那么这时候怎么解决呢?
其实很简单我们的render方法是有返回值的他的返回值其实就是,该文件中字符的个数,因为我们是字符流操作的因此他返回的内容就是文件中字符的个数。因此我们只需要对代码进行稍稍的改动即可

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

public class test_byte {
    public static void main(String[] args) throws IOException {
        Reader reader=new FileReader("d:/test.txt");
        char[] arr=new char[1024];
        int n=reader.read(arr);
        for(int i=0;i<n;i++){
            System.out.println(arr[i]);
        }
        //System.out.println(arr);
    }
}

但是这样就没问题了吗?当然不是我们这里是讲arr的长度设置的比文件中的字符个数要大因此才可以正常打印可是如果更小呢?如果更小的话很明显我们的代码时不行 的那么怎么办呢?这里就要讲解一下read的工作原理他的工作原理其实时讲文件中的内容尽可能的写到传入的数组中如果一次不行就多传几次因此我们可以加个while循环多次写入,并且当文件中的内容全部写到了数组中之后就会返回-1。代码如下

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

public class test_byte {
    public static void main(String[] args) throws IOException {
        Reader reader=new FileReader("d:/test.txt");
        char[] arr=new char[2];
        while(true){
            int n=reader.read(arr);
            if(n==-1){
                break;
            }
            for(int i=0;i<n;i++){
                System.out.println(arr[i]);
            }

        }

        //System.out.println(arr);
    }
}

那么如何写入呢?其实跟上面的方式是差别不大的。我们直接来看看代码就可以了。

import java.io.*;

public class test_byte {
    public static void main(String[] args) throws IOException {
        Writer writer=new FileWriter("d:/test.txt");
        String string=new String("JAVA你好");
        writer.write(string);
        writer.flush();
        //System.out.println(arr);
    }
}

这里可能会有困惑的地方应该就是flush这里,那么为什么要加个flush呢?其实是因为我们在进行写的时候其实不是直接写进文件中的而是先写进一个缓冲区里,这是为什么呢?
我们可以想一下一个人嗑瓜子,那么这个人嗑瓜子需要扔瓜子皮,垃圾桶此时又不在他身边,那么这时候他是磕一个瓜子然后去扔一个瓜子皮方便呢?还是把嗑下来的瓜子皮先用纸巾包着然后嗑够了后再去把这些嗑下的瓜子皮一下子全扔掉更好呢?很明显是第二种更好,此时这个纸巾其实就是缓冲区,那么如何告诉缓冲区我已经写好了赶紧把缓冲区中的数据刷新到内存中把,很简单其实就是用这个flush方法。

警告

但是上面的代码是一个有很严重bug那就是当我们进行读写操作后没有进行close,这是一个很严重的问题,我们在进行文件操作的时候必须要进行close,因为我们打开的文件其实都有一个数字去代表这个文件而这个数字时保存在了一个顺序表中的,这个顺序表如果被占满的话就会导致代码崩溃。那么为了防止这样的事件发生我们有什么办法呢?有的那就是将我们实例化出的对象放在try的小括号中

import java.io.*;

public class test_char {
    public static void main(String[] args) throws FileNotFoundException {
        try(Reader reader=new FileReader("d:/test.txt")){
            char[] arr=new char[1024];
            reader.read(arr);
            System.out.println(arr);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

字节流操作API

首先是字节流的类是什么呢?字节流的类有两个一个是InputStream,还有一个是OutputStream关于这两个类我们的分析如下

InputStream

import java.io.*;

public class test_char {
    public static void main(String[] args) throws FileNotFoundException {
        try(InputStream inputStream=new FileInputStream("d:/test.txt")) {
            byte[]arr=new byte[1024];
            int n=inputStream.read(arr);
            for(int i=0;i<n;i++){
                System.out.printf("%x ",arr[i]);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
那么此时的n就是这个文件中的字节数,而输出的数字就是这个文件中每个字符的ASCII码
此外呢我们读取文件还有一个办法那就是使用scanner代码如下

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

public class test_char {
    public static void main(String[] args) throws FileNotFoundException {
//        try(OutputStream outputStream=new FileOutputStream("d:/test.txt")){
//            String s="你好IO";
//            outputStream.write(s.getBytes());
//        }catch (IOException e){
//            e.printStackTrace();
//        }
        try (InputStream inputStream=new FileInputStream("d:/test.txt")){
            Scanner scanner=new Scanner(inputStream);
            String s=scanner.nextLine();
            System.out.println(s);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

在这里呢我们的scanner初始化的时候传入我们的字节流对象即可完成。

OutputStream

那么如何向文件中写呢?那就是用outputStream这个类使用方法和上面其实大同小异

import java.io.*;

public class test_char {
    public static void main(String[] args) throws FileNotFoundException {
        try(OutputStream outputStream=new FileOutputStream("d:/test.txt")){
            String s="你好IO";
            outputStream.write(s.getBytes());
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

这里我们要注意几点那就是因为我们此时时字节流,因此我们输入按道理来说也得是字节流但是因为我们无法去记住每个字符他的ASCII码因此java中边封装了getBytes()因此我们在写入的时候需要调用这个方法将我们想要写的内容转化为字节码。

当然除此之外还有没有别的办法呢?当然也有。代码如下

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

public class test_char {
    public static void main(String[] args) throws FileNotFoundException {
        try(OutputStream outputStream=new FileOutputStream("d:/test.txt")){
            PrintWriter printWriter=new PrintWriter(outputStream);
            printWriter.print("我爱你");
            printWriter.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
//        try (InputStream inputStream=new FileInputStream("d:/test.txt")){
//            Scanner scanner=new Scanner(inputStream);
//            String s=scanner.nextLine();
//            System.out.println(s);
//        }catch (IOException e){
//            e.printStackTrace();
//        }
    }
}

我们只需要创建一个PrintWriter 然后再new的时候将OutputStream 对象传进去就可以完成字节流向字符流的转换了。

想要和你并肩看夕阳我心之所向。

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

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

相关文章

【C++常用函数介绍】isalpha,isalnum、isdigit、islower、isupper 用法

首先 isalpha,isalnum、isdigit、islower、isupper 的使用方法都需要用到一个头文件 #include<ctype.h>其次 系统的介绍以上函数的用法 isalpha()用来判断一个字符是否为字母 isalnum&#xff08;&#xff09;用来判断一个字符是否为数字或者字母&#xff0c;也就是说…

四川尚熠电子商务有限公司靠谱吗?怎么样?

在当下数字化浪潮中&#xff0c;电子商务行业正以前所未有的速度蓬勃发展。四川尚熠电子商务有限公司&#xff0c;作为专注于抖音电商服务的企业&#xff0c;凭借其敏锐的市场洞察力和创新精神&#xff0c;正成为行业内的佼佼者&#xff0c;为众多品牌打开抖音电商市场的大门。…

Stable Diffusion扩散模型【详解】小白也能看懂!!

文章目录 1、Diffusion的整体过程2、加噪过程2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导&#xff0c;需要参考这篇文章&#xff1a; Stable Diffusion扩散模型推导公式的基础知识 1、Diffusion的整体…

2006-2022年各省研发投入强度数据/研究与试验发展(RD)经费投入强度数据(无缺失)

2006-2022年各省研发投入强度数据/研究与试验发展(R&D)经费投入强度数据(无缺失) 1、时间:2006-2022年 2、范围&#xff1a;31省 3、来源&#xff1a;科技年鉴 4、指标&#xff1a;研发投入强度/研究与试验发展(R&D)经费投入强度 5、指标解释&#xff1a;研发投入…

算法沉淀 —— 动态规划(子序列问题(上))

算法沉淀 —— 动态规划&#xff08;子序列问题&#xff08;上&#xff09;&#xff09; 前言一、最长递增子序列二、摆动序列三、 最长递增子序列的个数四、最长数对链 前言 几乎所有的动态规划问题大致可分为以下5个步骤&#xff0c;后续所有问题分析都将基于此 1.、状态表示…

main函数的三个参数

main函数有三个参数 int main(int argc,char *argv[],char *env[]) 第一个参数argc argc:命令行参数的个数&#xff0c;当我们在命令行进行某些程序时需要一些参数 第二个参数argv argv:它是一个指针数组&#xff0c;里面存的是命令行参数的地址 第三个参数env env&…

如何减少与客户对需求理解的误差

大家好&#xff0c;我是不会魔法的兔子&#xff0c;持续分享项目管理中的风险及预防问题。 今天来说一说与客户对需求产生理解误差的问题&#xff0c;因为前些天看到小伙伴的吐槽&#xff0c;说明明是已经和客户就某个需求及解决方案说好了&#xff0c;结果东西做出来&#xf…

MySQL故障排查与优化

一、MySQL故障排查 1.1 故障现象与解决方法 1.1.1 故障1 1.1.2 故障2 1.1.3 故障3 1.1.4 故障4 1.1.5 故障5 1.1.6 故障6 1.1.7 故障7​ 1.1.8 故障8 1.1.9 MySQL 主从故障排查 二、MySQL优化 2.1 硬件方面 2.2 查询优化 一、MySQL故障排查 1.1 故障现象与解决方…

NVIDIA Jetson Xavier NX入门-镜像为jetpack5(3)——pytorch和torchvision安装

NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#xff08;3&#xff09;——pytorch和torchvision安装 镜像为jetpack5系列&#xff1a; NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#xff08;1&#xff09;——镜像烧写 NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#…

Stream API

Stream 是数据渠道&#xff0c;用于操作数据源&#xff08;集合、数组等&#xff09;所生成的元素序列。 Stream 和 Collection 集合的区别&#xff1a;Collection 是一种静态的内存数据结构&#xff0c; 讲的是数据&#xff0c;而 Stream 是有关计算的&#xff0c;讲的是计算。…

小林coding图解计算机网络|基础篇02|键入网址到网页显示,期间发生了什么?

小林coding网站通道&#xff1a;入口 本篇文章摘抄应付面试的重点内容&#xff0c;详细内容还请移步&#xff1a;小林coding网站通道 文章目录 孤单小弟——HTTP真实地址查询——DNS指南好帮手——协议栈可靠传输——TCP远程定位——IP两点传输——MAC出口——网卡送别者——交…

Linux是什么,该如何学习

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Linux的起源与发展 2、Linux在现代计算机领域…

Gatekeep AI:文本转视频教学工具,开启智能学习新纪元

在当今的数字时代,技术的进步不断改变着我们学习和理解知识的方式。 Gatekeep AI 就是这样一款令人兴奋的工具,它专注于将数学和物理问题通过文本提示转化为生动的视频。 特点与优势: 直观的可视化:将复杂的数学和物理概念以直观的视频形式呈现。快速生成:根据用户提供的…

SpringBoot + Vue + Nginx前后端分离项目本地部署(Win)

SpringBoot Vue Nginx前后端分离项目本地部署步骤 本地部署所需步骤 将后端打包好的jar文件和前端生成的静态资源文件放入同一目录启动Spring Boot应用配置Nginx并重启访问 http://your_domain 查看部署效果 前端Vue项目部署 将写好的vue代码的目录下运行 npm run build …

arm裸机(1)、点灯|按键

芯片是S3C2440 首先看原理图&#xff0c;led_1234分别对应引脚GPB 5678 设置引脚为输出 向寄存器相应位写入 #define GPBCON (*(volatile unsigned long *)0x56000010) //p5 6 7 8 void led_init(void) {GPBCON & ~(0x3 << 10);GPBCON | (0x1 <<…

网络编程(TCP、UDP)

文章目录 一、概念1.1 什么是网络编程1.2 网络编程中的基本知识 二、Socket套接字2.1 概念及分类2.2 TCP VS UDP2.3 通信模型2.4 接口方法UDP数据报套接字编程TCP流套接字编程 三、代码示例3.1 注意点3.2 回显服务器基于UDP基于TCP 一、概念 首先介绍了什么是网络编程&#xff…

【C语言】_文件内容操作:顺序读写

目录 常用函数 1. 字符输入、输出函数 2. 文本行输入、输出函数 3. 格式化输入、输出函数 4. 二进制输入、输出函数 常用函数 功能函数名适用于字符输入函数fgetc所有输入流字符输出函数fputc所有输出流文本行输入函数fgets所有输入流文本行输出函数fputs所有输出流格式化…

材料物理 笔记-4

原内容请参考哈尔滨工业大学何飞教授&#xff1a;https://www.bilibili.com/video/BV18b4y1Y7wd/?p12&spm_id_frompageDriver&vd_source61654d4a6e8d7941436149dd99026962 或《材料物理性能及其在材料研究中的应用》&#xff08;哈尔滨工业大学出版社&#xff09; 离…

基于springboot+vue+Mysql的招生管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

RAID 0阵列扩容后的磁盘扩展操作

正文共&#xff1a;777 字 21 图&#xff0c;预估阅读时间&#xff1a;1 分钟 上次操作RAID 0的扩容&#xff08;如何操作RAID 0阵列的扩容&#xff1f;&#xff09;&#xff0c;因为耗时太长进度没有变化&#xff0c;就没再管它了。后来发现&#xff0c;右上角有一个“重新扫描…