JAVA文件IO, File类, 字符流,字节流

news2024/11/26 19:33:28

文章目录

  • 文件IO
    • 1. File
    • 2. IO流
      • 2.1 字符流
        • 2.1.1 Reader
        • 2.1.2 Writer
      • 2.2 字节流
        • 2.2.1 InputStream
        • 2.2.2 FileInputStream
        • 2.2.3 利用Scanner进行字符读取
        • 2.2.4 OutputStream

文件IO

I: Input, 从硬盘往内存读数据

O: Output, 从内存往硬盘输出数据

1. File

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

构造方法

方法说明
File(File parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例
File(String pathname)根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者相对路径
File(String parent, String child)根据父目录 + 孩子文件路径,创建一个新的 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(File dest)进行文件改名,也可以视为我们平时的剪切、粘贴操作
booleancanRead()判断用户是否对文件有可读权限
booleancanWrite()判断用户是否对文件有可写权限

代码示例

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

输出

text.txt

D:\

D:\text.txt

D:\text.txt

D:\text.txt

===========================

.

.\text.txt

D:\JAVA\java\system_code.\text.txt

D:\JAVA\java\system_code\text.txt

public static void main(String[] args) throws IOException {
    File file = new File("./test.txt");
    System.out.println(file.exists());
    System.out.println(file.isFile());
    System.out.println(file.isDirectory());
    //创建文件
    file.createNewFile();//若当前文件已经存在, 也不会重新创建一个

    System.out.println(file.exists());
    System.out.println(file.isFile());
    System.out.println(file.isDirectory());
}

输出

true

true

false

===========================

true

true

false

public static void main(String[] args) throws IOException {
    File file = new File("./text.txt");
    System.out.println(file.exists());
    file.delete();
    System.out.println("文件已删除");
    System.out.println(file.exists());
}

输出

false

文件已删除

false

public static void main(String[] args) throws IOException {
    File file = new File("text.txt");
    System.out.println(file.exists());
    //等到程序结束前再删除
    file.deleteOnExit();
    System.out.println(file.exists());
}

输出

true

true

public static void main(String[] args) {
    File file = new File("./testDir");
    file.mkdir();
    System.out.println(file.exists());
    System.out.println(file.isDirectory());
    
    File file1 = new File("./testDir/aaa/bbb/ccc");
    file1.mkdirs();
    System.out.println(file1.exists());
    System.out.println(file1.isDirectory());
}

输出

true

true

true

true

public static void main(String[] args) {
    File file = new File("./test.txt");
    File file1 = new File("./testRename.txt");
    
    System.out.println("file是否存在: " + file.exists());
    System.out.println("file1是否存在: " + file1.exists());
    
    System.out.println("renameTo执行是否成功: "+file.renameTo(file1));
    
    System.out.println("file是否存在: " + file.exists());
    System.out.println("file1是否存在: " + file1.exists());
}

输出

file是否存在: true

file1是否存在: false

renameTo执行是否成功: true

file是否存在: false

file1是否存在: true

public static void main(String[] args) throws IOException {
    File file = new File("./test.txt");
    File file1 = new File("./src/test2.txt");

    System.out.println("file是否存在: " + file.exists());
    System.out.println("file1是否存在: " + file1.exists());

    System.out.println("file的路径" + file.getCanonicalPath());

    System.out.println("renameTo执行是否成功: "+file.renameTo(file1));

    System.out.println("file是否存在: " + file.exists());
    System.out.println("file1是否存在: " + file1.exists());

    System.out.println("file1的路径" + file1.getCanonicalPath());

}

输出

file是否存在: true

file1是否存在: false

file的路径D:\JAVA\java\system_code\test.txt

renameTo执行是否成功: true

file是否存在: false

file1是否存在: true

file1的路径D:\JAVA\java\system_code\src\test2.txt

2. IO流

将硬盘中的数据比喻为池中的水

往池中加水, 相当于数据从内存往硬盘中流动, 称作输出流

从池中放水, 相当于数据从硬盘往内存中流, 称作输入流

IO流可以分为 字节流 , 字符流 两大类

这些类都有各自不同的特性, 但是使用方法还是类似的:

  1. 构造方法: 打开文件

  2. close方法: 关闭文件

    close方法一定要执行到, 如果使用完不关闭, 就会导致文件资源泄露 (尤其是在7*24小时运转的服务器上) 进而导致文件都打不开, 使服务器宕机.

    如何保证close方法一定能执行的到呢?

    1. 使用try-finally, 将close写入finally代码块

    2. 使用try with resources创建流对象. 例如

    try (Reader reader = new FileReader("D:/test.txt");
         Reader reader1 = new FileReader("");
         Reader reader2 = new FileReader("");
         ...) {
    	//代码
    }
    

    只要try代码块执行结束, 就会自动调用close方法.

  3. 如果衍生自InputStream或者Reader, 就可以使用read方法读文件

  4. 如果衍生自OutputStream或者Writer, 就可以使用write方法写文件

2.1 字符流

字符流, 顾名思义, 以操作字符为单位, 针对文本文件

2.1.1 Reader

read方法

方法作用返回值
int read()一次读一个字符以int类型返回读到的字符. 如果返回值为-1, 表示文件已经读完, 或者读到EOF.
int read(char cbuf[])一次读若干个字符, 并把读到的内容填充到cbuf[]中返回实际读到的字符个数
int read(char cbuf[], int off, int len)从第off个字符开始, 将字符读入数组, 一共读len个读取的字符数,如果已到达流的结尾,则返回-1

代码案例

public static void main(String[] args) throws IOException {
    try (Reader reader = new FileReader("D:/test.txt")) {
        while (true) {
            char[] buf = new char[1024];
            int n = reader.read(buf);
            if(n == -1) {
                break;
            }
            for (int i = 0; i < n; i++) {
                System.out.print(buf[i] + " ");
            }
        }
    }
}

在这里插入图片描述

2.1.2 Writer

write方法

方法说明
void write(int c)写入单个字符。
void write(char cbuf[])写入字符数组。
void write(char cbuf[], int off, int len)写入字符数组的一部分。cbuf -字符数组off -开始写入字符的偏移量len -要写入的字符数
void write(String str)写入字符串
void write(String str, int off, int len)写入字符串的一部分。str -字符串off -开始写入字符的偏移量len -写入字符的数目

代码示例

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

在这里插入图片描述

这里可能就会有疑问了, 文件里面之前的内容呢?

输出流对象(无论字节流还是字符流), 再打开文件之后, 清空文件内容.

如果不想被清空, 那就使用追加写方式打开文件.

Writer writer = new FileWriter("D:/test.txt", true)

在构造方法上, 写一个true, 便可

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

在这里插入图片描述

2.2 字节流

字节流, 顾名思义, 以操作字节为单位, 针对二进制文件

2.2.1 InputStream

方法

返回值类型方法说明
intread()读取一个字节的数据,返回 -1 代表已经完全读完了
intread(byte[] b)最多读取 b.length 字节的数据到 b 中,返回实际读到的数; -1 代表以及读完了
intread(byte[] b, int off, int len)最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了
voidclose()关闭字节流

说明

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

2.2.2 FileInputStream

构造方法

方法说明
FileInputStream(File file)利用 File 构造文件输入流
FileInputStream(String name)利用文件路径构造文件输入流

代码示例

public static void main(String[] args) {
    try(InputStream inputStream = new FileInputStream("D:/test.txt")) {
        while (true) {
            byte[] bytes = new byte[1024];
            int n = inputStream.read(bytes);
            if (n == -1) {
                break;
            }
            for (int i = 0; i < n; i++) {
                System.out.printf("%x ", bytes[i]);
            }
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

在这里插入图片描述

读到的字符, 我们更期望的是把他转化成字符串, 更直观. 所以我们可以借助一些额外的工具类, 就可以完成从字节/字符到字符串的转换.

一. 是使用String的构造方法. 但这种方式不够优雅.

String s = new String(bytes, 0, n, "utf8");
System.out.println(s);

在这里插入图片描述

二. 是Scanner.

2.2.3 利用Scanner进行字符读取

我们来看一下Scanner的构造方法

在这里插入图片描述

其中, 构造方法的参数中有InputStream, 也就是说我们可以往里面传字节流. 实际上, 我们经常写的new Scanner(System.in)中的in也是一个字节流

在这里插入图片描述

其实在操作系统中, "文件"是一个广义的概念

  • System.in是一个特殊的文件, 对应到"标准输入"
  • 硬盘上的文件, 也是文件
  • 网卡(socket), 也是文件

Scanner都是一视同仁的, 只是把当前读到的字节数据进行转换, 不关心这个数据的来源.

那么上述读取文件的代码就可以这样写了

public static void main(String[] args) throws IOException {
    try(InputStream inputStream = new FileInputStream("D:/test.txt")) {
        Scanner scanner = new Scanner(inputStream);
        //Scanner scanner = new Scanner(inputStream, "utf8");
        //从文件中读取
        while (scanner.hasNext()) {
            String s = scanner.next();
            System.out.print(s + " ");
        }
    }
}

在这里插入图片描述

但是Scanner只适合读取文本文件, 不适合读取二进制文件

2.2.4 OutputStream

方法

返回值类型方法说明
voidwrite(int b)将指定字节写入此输出流。
voidwrite(byte[] b)将 b 这个字节数组中的数据全部写入 os 中
voidwrite(byte b[], int off, int len)将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
voidclose()关闭字节流
voidflush()刷新此输出流并强制写出任何缓冲的输出字节。

我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。

OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,

所以使用 FileOutputStream

OutputStream 的使用方法和Writer完全一样, 只不过不能写入字符, 字符串.

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

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

相关文章

Android控件全解手册 - 任意View缩放平移工具-实现思路和讲解

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

御云出海记|巴西市场,数字化转型与地区增长的新篇章

在11月的阳光下&#xff0c;巴西圣保罗的热情与活力成为了南半球市场的缩影&#xff0c;尤其是在华为云巴西峰会上。 云峰会亮点 11月22日&#xff0c;圣保罗举办的华为云巴西峰会成为了当地科技界的焦点。此次峰会聚集了数百位政府官员、行业领袖、专家学者&#xff0c;共同讨…

C++基础 -10- 类

类的格式 public:公共成员 类外可访问 protected:保护成员 类外不可访问 private:私有成员 类外不可访问 class base {public:int a;protected:int b;private:int c;};

Linux处理系统常见命令

目录 1 sudo 1.1 介绍 1.2 配合 2 ifconfig与ping 2.1 ifconfig 2.2 ping 3 kill 4 apt-get 4.1 介绍 4.2 配合 5 history 6 clear 7 env 1 sudo 1.1 介绍 给这条命令最高权限&#xff0c;比如 sudo cp something.txt /usr/bin/something.txt 1…

用C++和python混合编写数据采集程序?

之前看过一篇文章&#xff0c;主要阐述的就是多种语言混合编写爬虫程序&#xff0c;结合各种语言自身优势写一个爬虫代码是否行得通&#xff1f;觉得挺有意思的&#xff0c;带着这样的问题&#xff0c;我尝试着利用我毕生所学写了一段C和python混合爬虫程序&#xff0c;目前运行…

echarts点击事件

有这么个需求要点击叶片的时候跳转页面 代码&#xff1a;点击之后 报错了 解决办法 1、使用箭头函数&#xff08;箭头函数没有自己的 this&#xff0c;所以在箭头函数中使用 this 时&#xff0c;其指向与外层作用域相同。&#xff09;或者使用闭包来解决上下文的问题。 2、使…

Java抽象类:类的幕后黑手,提供继承和扩展的框架。

&#x1f451;专栏内容&#xff1a;Java⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、抽象类的概念二、注意事项三、抽象类的作用 一、抽象类的概念 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘…

【JavaSE学习专栏】第02篇 流程控制

文章目录 1 用户交互Scanner2 顺序结构3 选择结构3.1 if单选择结构3.1.1 语法结构3.1.2 案例 3.2 if双选择结构3.2.1 语法结构3.2.2 案例 3.3 if多选择结构3.3.1 语法结构3.3.2 案例 3.4 嵌套的if结构3.4.1 语法结构3.4.2 案例 3.5 switch多选择结构3.5.1 语法结构3.5.2 案例 4…

Opencv | 直方图均衡化

import cv2 #opencv 读取的格式是BGR import numpy as np import matplotlib.pyplot as plt #Matplotlib是RGB %matplotlib inline def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows() cv2.calcHist(images,channels,mask,histSize,ranges) - …

PAT-10道题

PAT算法刷题 1002 1002 一&#xff1a;对于每一的1到6都进行枚举&#xff0c;进行递归操作 二&#xff1a;如果位数到了指定的n的时候&#xff0c;递归的条件&#xff0c;进行判断是否可以整除操作 #include<iostream> #include<algorithm> using namespace std; l…

Programming Abstractions in C阅读笔记:p202-p234

《Programming Abstractions in C》学习第65天&#xff0c;p202-p234总结。 一、技术总结 完成第五章学习&#xff0c;第五章介绍递归在实际问题中的进一步应用&#xff0c;例如汉诺塔问题&#xff0c;数学中的排列问题&#xff0c;更有难度。使用递归解决问题时有时候需要借…

Element-ui合并table表格列方法

merageCell({ row, column, rowIndex, columnIndex }) {if (columnIndex 0 || columnIndex 1) {const property columnIndex 0 ? name : firstDeptName;// 获取当前行的property&#xff0c;这里看自己的需要&#xff0c;改成根据哪个去判断const currentPropertyVal row…

带残差连接的ResNet18

目录 1 模型构建 1.1 残差单元 1.2 残差网络的整体结构 2 没有残差连接的ResNet18 2.1 模型训练 2.2 模型评价 3 带残差连接的ResNet18 3.1 模型训练 3.2 模型评价 4 与高层API实现版本的对比实验 总结 残差网络&#xff08;Residual Network&#xff0c;ResNet&#xff09;…

C语言——数组转换

将的两行三列数组转换为三行两列的数组 #define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int a[2][3]{{1,2,3},{4,5,6}};int b[3][2],i,j;for ( i 0; i <1; i){for ( j 0; j <2; j){printf("%5d",a[i][j]);b[j][i]a[i][j];}printf(&…

项目七 熟练使用Vim程序编辑器与shell

项目七 熟练使用Vim程序编辑器与shell #职业能力目标和要求 1&#xff0c;学会使用vim编辑器。 2&#xff0c;了解shell的强大功能和shell的命令解释过程。 3&#xff0c;学会使用重定向和管道的方法。 4&#xff0c;掌握正则表达式的使用方法。7.1 熟悉使用vim编辑器 7.1.1 …

【TC3xx芯片】TC3xx芯片的Clock System功能详解

目录 前言 正文 1.时钟源 1.1 有源晶振和无源晶振 1.1.1 无源晶振 1.1.2 有源晶振 1.1.3 有源晶振和无源晶振的区别 1.1 振荡器电路&#xff08;OSC&#xff09; 1.1.1外部输入时钟模式 1.1.2 外部晶体 / 陶瓷谐振器模式 1.1.3 OSC控制寄存器 1.1.4 配置OSC 1.1.5…

C语言常见算法

算法&#xff08;Algorithm&#xff09;&#xff1a;计算机解题的基本思想方法和步骤。算法的描述&#xff1a;是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述&#xff0c;包括需要什么数据&#xff08;输入什么数据、输出什么结果&#xff09;、采用什么结构、使…

Vue3的transition标签以及animate.css使用详解

一&#xff1a;前言 在项目开发中&#xff0c;有一种特殊情况是使用动画过渡去完成某个效果。比如淡入淡出&#xff0c;或者在动画完成后执行某些操作等。在以前开发中我们通常会选择使用 CSS3 进行研发。但是这样会有很多不好的地方&#xff0c;比如最原始化的封装&#xff0c…

纵行科技获评“汽车物流行业优秀技术装备供应商”

近日&#xff0c;由中国物流与采购联合会主办&#xff0c;中物联汽车物流分会承办的“2023年全国汽车物流行业年会”在湖北十堰盛大召开。本次年会集合了汽车整车、零部件、售后备件、进出口物流企业和物流装备技术企业、科研机构及院校等&#xff0c;分享汽车物流行业现状、相…

使用STM32微控制器实现光电传感器的接口和数据处理

光电传感器在许多领域中被广泛应用&#xff0c;例如工业自动化、智能家居等。本文将介绍如何使用STM32微控制器实现光电传感器的接口和数据处理的方案&#xff0c;包括硬件设计、引脚配置、数据采集、滤波和阈值判断等关键步骤&#xff0c;并给出相应的代码示例。 一、引言 光…