【文件操作与IO】Java中如何操作文件

news2024/10/7 4:32:22

目录

 Java 中操作文件

File 概述

属性

构造方法

方法

代码示例

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

 InputStream 概述

FileInputStream 概述

利用 Scanner 进行字符读取

OutputStream 概述

利用 OutputStreamWriter 进行字符写入

利用 PrintWriter 找到我们熟悉的方法

代码参考

如何按字节进行数据读

如何按字节进行数据写

如何按字符进行数据读

如何按字符进行数据写


 Java 中操作文件


操作系统的一个重要功能就是对文件的管理,每个操作系统都有自己的一套系统API调用,Java作为一个跨平台的语言,JVM针对不同的操作系统做了一层封装,我们只需使用JDK提供的关于文件操作的API就可以完成不同的系统上的文件操作。

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

File 概述

属性

修饰符及类型 

属性

说明

static String

pathSeparator

依赖于系统的路径分隔符,String 类型的表示

static char

pathSeparator

依赖于系统的路径分隔符,char 类型的表示

构造方法

方法

修饰符及返回

值类型

方法签名

说明

String

getParent()

返回 File 对象的父目录文件路径

String

getName()

返回 FIle 对象的纯文件名称

String

getPath()

返回 File 对象的文件路径

String

getAbsolutePath()

返回 File 对象的绝对路径

String

getCanonicalPath()

返回 File 对象的修饰过的绝对路径

boolean

exists()

判断 File 对象描述的文件是否真实存在

boolean

isDirectory()

判断 File 对象代表的文件是否是一个目录

boolean

isFile()

判断 File 对象代表的文件是否是一个普通文件

boolean

createNewFile()

根据 File 对象,自动创建一个空文件。成功创建后返

回 true

boolean

delete()

根据 File 对象,删除该文件。成功删除后返回 true

void

deleteOnExit()

根据 File 对象,标注文件将被删除,删除动作会到

JVM 运行结束时才会进行

String[]

list()

返回 File 对象代表的目录下的所有文件名

File[]

listFiles()

返回 File 对象代表的目录下的所有文件,以 File 对象

表示

boolean

mkdir()

创建 File 对象代表的目录

boolean

mkdirs()

创建 File 对象代表的目录,如果必要,会创建中间目

boolean

renameTo(File

dest)

进行文件改名,也可以视为我们平时的剪切、粘贴操

boolean

canRead()

判断用户是否对文件有可读权限

boolean

canWrite()

判断用户是否对文件有可写权限

代码示例

示例1

观察 get 系列的特点和差异

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("..\\hello-world.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());
   }
}

运行结果

..
hello-world.txt
..\hello-world.txt
D:\代码练习\文件示例1\..\hello-world.txt
D:\代码练习\hello-world.txt

示例2

普通文件的创建、删除

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("hello-world.txt"); // 要求该文件不存在,才能看到相同的现象
        System.out.println(file.exists());
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.createNewFile());
        System.out.println(file.exists());
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.createNewFile());
   }
}

运行结果

false
false
false
true
true
false
true
false

示例3

观察 deleteOnExit 的现象

import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("some-file.txt"); // 要求该文件不存在,才能看到相同的现象
        System.out.println(file.exists());
        System.out.println(file.createNewFile());
        System.out.println(file.exists());
        file.deleteOnExit();
        System.out.println(file.exists());
   }
}

运行结果

false
true
true
true

程序运行结束后,文件还是被删除了

示例4

观察目录创建

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File dir = new File("some-parent\\some-dir"); // some-parent 和 somedir 都不存在
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
        System.out.println(dir.mkdir());
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
   }
}

运行结果

false
false
false
false
false

mkdir() 的时候,如果中间目录不存在,则无法创建成功; mkdirs() 可以解决这个问题。

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File dir = new File("some-parent\\some-dir"); // some-parent 和 somedir 都不存在
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
        System.out.println(dir.mkdirs());
        System.out.println(dir.isDirectory());
        System.out.println(dir.isFile());
   }
}

运行结果

false
false
true
true
false

示例5

观察文件重命名

import java.io.File;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException {
        File file = new File("some-file.txt"); // 要求 some-file.txt 得存在,可以是普通文件,可以是目录
        File dest = new File("dest.txt");   // 要求 dest.txt 不存在
        System.out.println(file.exists());
        System.out.println(dest.exists());
        System.out.println(file.renameTo(dest));
        System.out.println(file.exists());
        System.out.println(dest.exists());
   }
}

运行结果

true
false
true
false
true

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


数据流分类

 InputStream 概述

方法

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

说明

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

FileInputStream 概述

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

示例

这里我们把文件内容中填充中文看看,注意,写中文的时候使用 UTF-8 编码。hello.txt 中填写 "你好中国"

注意:这里我利用了这几个中文的 UTF-8 编码后长度刚好是 3 个字节和长度不超过 1024 字节的现状,但这种方式并不是通用的

import java.io.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
            byte[] buf = new byte[1024];
            int len;
            while (true) {
                len = is.read(buf);
                if (len == -1) {
                    // 代表文件已经全部读完
                    break;
               }
                // 每次使用 3 字节进行 utf-8 解码,得到中文字符
                // 利用 String 中的构造方法完成
                // 这个方法了解下即可,不是通用的解决办法
                for (int i = 0; i < len; i += 3) {
                    String s = new String(buf, i, 3, "UTF-8");
                    System.out.printf("%s", s);
               }
           }
       }
   }
}

利用 Scanner 进行字符读取

上述例子中,我们看到了对字符类型直接使用 InputStream 进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该工作,就是 Scanner 类。

构造方法
说明
Scanner(InputStream is, String charset)
使用 charset 字符集进行 is 的扫描读取
示例
import java.io.*;
import java.util.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("hello.txt")) {
           try (Scanner scanner = new Scanner(is, "UTF-8")) {
               while (scanner.hasNext()) {
                   String s = scanner.next();
                   System.out.print(s);
               }
           }
       }
   }
}

OutputStream 概述

方法
修饰
符及
返回
值类
方法签名
说明
void
write(int b)
写入要给字节的数据
void
write(byte[]
b)
b 这个字符数组中的数据全部写入 os
int
write(byte[]
b, int off,
int len)
b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len
void
close()
关闭字节流
void
flush()
重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream
了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的
一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写
入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的
数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,
调用 flush (刷新)操作,将数据刷到设备中。

说明

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

利用 OutputStreamWriter 进行字符写入

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            String s = "你好中国";
            byte[] b = s.getBytes("utf-8");
            os.write(b);
            // 不要忘记 flush
            os.flush();
       }
   }
}

利用 PrintWriter 找到我们熟悉的方法

上述,我们其实已经完成输出工作,但总是有所不方便,我们接来下将 OutputStream 处理下,使用PrintWriter 类来完成输出,因为

PrintWriter 类中提供了我们熟悉的 print/println/printf 方法
import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8")) {
                try (PrintWriter writer = new PrintWriter(osWriter)) {
                    writer.println("我是第一行");
                    writer.print("我的第二行\r\n");
                    writer.printf("%d: 我的第三行\r\n", 1 + 1);
                    writer.flush();
               }
           }
       }
   }
}

代码参考


如何按字节进行数据读

try (InputStream is = ...) {
    byte[] buf = new byte[1024];
    while (true) {
        int n = is.read(buf);
        if (n == -1) {
            break;
       }
        // buf 的 [0, n) 表示读到的数据,按业务进行处理
   }
}

如何按字节进行数据写

try (OutputStream os = ...) {
    byte[] buf = new byte[1024];
    while (/* 还有未完成的业务数据 */) {
        // 将业务数据填入 buf 中,长度为 n
        int n = ...;
        os.write(buf, 0, n);
   }
    os.flush(); // 进行数据刷新操作
}

如何按字符进行数据读

try (InputStream is = ...) {
    try (Scanner scanner = new Scanner(is, "UTF-8")) {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            // 根据 line 做业务处理
       }
   }
}

如何按字符进行数据写

try (OutputStream os = ...) {
    try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8")) {
        try (PrintWriter writer = new PrintWriter(osWriter)) {
            while (/* 还有未完成的业务数据 */) {
                writer.println(...);
           }
            writer.flush(); // 进行数据刷新操作
       }
   }
}

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

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

相关文章

D. A Wide, Wide Graph(树的直径)

Problem - 1805D - Codeforces 给定一棵包含n个节点的树&#xff08;一个无环联通图&#xff09;&#xff0c;对于一个固定的整数k&#xff0c;定义Gk为一个具有n个节点的无向图&#xff0c;其中只有当在给定树中节点u和v之间的距离至少为k时才存在边。 对于从1到n的每个k&…

undefined reference to `tputs‘

昨天在Debian11 上编译 bluez 的时候&#xff0c;看这里&#xff0c;出现了如下这个错误&#xff0c;一般这种未定义的错误提示都是没有链接正确的库导致&#xff0c;但是搞了很久都没解决。 奇怪的是之前在 Centos 上编译却没有遇到这个问题&#xff0c;而且在 configure 时也…

做Java开发,真的“穷途末路”了吗?浅谈从2018-2023年,这行到底“卷”成了啥样

文章目录 一、火爆的行业1、裁员潮引发的行业惶恐2、国情下的行业现状3、时代的快速发展 二、Java开发“卷”成了啥样1、2013年2、2018年3、2013年4、真的需要这么多知识吗 三、大龄程序员何去何从引用来处 一、火爆的行业 “程序员”这个代名词&#xff0c;似乎总是跟“高薪”…

基于多进程并发-进程通讯之管道(pipe)

一、管道&#xff08;pipe&#xff09; 所谓的管道&#xff0c;就是内核⾥⾯的⼀串缓存&#xff08;Pipe&#xff09;。一个进程从管道的⼀端写⼊的数据&#xff0c;实际上是缓存在内核中的&#xff0c;另⼀端读取&#xff0c;也就是从内核中读取这段数据。 特性&#xff1a;…

windwos2016 由于没有远程桌面授权服务器可以提供许可证

一、问题&#xff1a; 经常会遇到&#xff0c;server2016、server2012、server2008操作系统&#xff0c;安装远程桌面服务之后没有激活&#xff0c;经过120天到期之后&#xff0c;没办法再使用&#xff0c;重新安装激活远程桌面服务也不能用。 二、具体的报错如下图&#xff…

归并排序详解-附Python代码

排序思路 将输入的列表递归分解成若干个有序的子列表&#xff08;只含有一个元素&#xff09;&#xff1b;将分解后的有序子列表两两归并成一个新的有序列表&#xff1b;重复步骤2&#xff0c;直到完成排序。 重点&#xff1a;如何定义一个归并函数&#xff0c;可以将两个有序…

Qt-自定义控件

Qt-自定义控件 简单使用 首先创建一个工程 在现有的工程上添加文件&#xff0c;选择Qt设计师界面类 选择Widget 添加两个控件之后&#xff0c;选择水平布局 将刚刚自定义的控件smallWidget放置在原始的控件中 首先在原始工程的ui界面 随便放置一个widget 选择&#xff…

我的内网渗透-代理转发(1)

概念 网关 必须经过 用来进行路由转发的设备&#xff0c;网关的作用是让不同网段之间能够通信 代理 委托访问 无论代理后面挂了几台设备&#xff0c;都认为是从代理进行访问&#xff0c;对外只表现为代理一台。外部认为是与代理进行…

计算机提示xinput1_3.dll丢失,三个详细修复方法

打开《绝地求生》游戏的时候&#xff0c;计算机提示xinput1_3.dll丢失&#xff0c;无法启动运行。重新安装一遍游戏依然无法启动运行。这个是由于xinput1_3.dll文件是属于电脑系统DirectX9.0的一个组件&#xff0c;用于提供输入和输出功能。它包含了各种接口和函数&#xff0c;…

spi控制器和spi设备的加载过程

spi控制器都是挂在platform总线上的&#xff0c;所以要等platform总线上的设备驱动加载spi控制器完成后才能加载spi设备。 1.spi控制器加载 由spi控制器驱动程序调用spi_register_master来完成spi控制器驱动加载 int spi_register_master(struct spi_master *master) { ... s…

【ubuntu20.04上构建qemu启动linux kernel】

参考Ubuntu环境下使用qemu搭建arm64运行环境 - 简书 一、交叉编译工具 sudo apt install gcc-aarch64-linux-gnu aarch64-linux-gnu-gcc -v 二、linux内核编译 git clone https://github.com/torvalds/linux.git cp arch/arm64/configs/virt.config .config make ARCHarm64 m…

并网逆变器杂记1-VO-DCC双环控制

NOTE1&#xff1a; 母线电压恒定的条件是&#xff1a; PV输出功率 &#xff0c;等于逆变侧消耗功率 假设&#xff1a;PV侧给母线输入10A &#xff0c;但是逆变侧消耗1A&#xff0c;此时母线Udc会升高 反之PV输入1A&#xff0c;消耗10A&#xff0c;母线Udc会降低。 NOTE2&#…

【IP地址】使用这个免费工具轻松获取地理位置

文章目录 前言一、Ip-API二、使用示例2.1、语言2.2、数据格式 三、简单示例四、更好的服务五、需要注意的点结尾 前言 今天分享一个免费的在线工具来查询IP地址所在的地理位置。可以通过IP地址所属的网络运营商和其他相关信息来确定设备的位置&#xff0c;包括国家、地区、城市…

CentOs中操作用户命令(添加或删除)

1、不添加任何参数,创建 zhangsan 用户 不加参数时,创建用户默认创建一个用户目录以及用户和组同名,且UID和GID相同 useradd zhangsan 用 id和 ll 命令查看一下,是否成功创建用户目录以及用户和用户组 id ll uid1003( zhangsan) gid1003( zhangsan) 组1003( zhangsan) 2…

Obsidian 与 Typora 图片兼容保存路径一致设置

目录 一、问题二、解决方法 Obsidian官网 &#xff1a; https://obsidian.md/ Your thoughts are yours. 你的想法就是你的。 Obsidian stores notes on your device, so you can access them quickly, even offline. No one else can read them, not even us. 黑曜石将笔记存储…

Java——基础语法

文章目录 1. 变量&#xff1a;变量的声明和初始化变量的作用域变量的命名规则常量 2. 运算符&#xff1a;算术运算符关系运算符逻辑运算符位运算符其他运算符 3. 流程控制&#xff1a;分支结构循环结构跳转控制 4. 类与对象&#xff1a;类的概念对象的概念类的成员构造方法和析…

深入理解深度学习——BERT派生模型:T5(Text to Text Transfer Transformer)

分类目录&#xff1a;《深入理解深度学习》总目录 T5的全称为Text to Text Transfer Transformer&#xff0c;是谷歌提出的预训练语言模型领域的通用模型&#xff0c;该模型将所有自然语言问题都转化成文本到文本的形式&#xff0c;并用一个统一的模型解决。为了得到大一统的高…

Tkinter创建列表使用方法

前言 ttk.Treeview 是 Tkinter 模块中的一个组件&#xff0c;它提供了一个可用于显示层次结构数据的树状列表。它具有以下特点和功能&#xff1a; 显示层次结构&#xff1a;ttk.Treeview支持以树状结构显示数据。每个节点可以有子节点&#xff0c;从而形成层次结构。用户可以展…

GPT-2源码实现及GPT-3、GPT-3.5、GPT-4及GPT-5内幕解析(三)

GPT-2源码实现及GPT-3、GPT-3.5、GPT-4及GPT-5内幕解析(三) 5.3 GPT-3 内幕机制可视化解析 GPT-3是一个基于Transformer的语言模型,通过不同的层次提取语言不同层面的特性,构建整个语言的语义信息,它学习的过程跟人类正常学习的过程是类似的,开始的时候是一个无监督预训练…

材料表面与界面 关键概念介绍

目录 1. Conductivity and two general modes of charge transport in solid-state materials (Fig. 1b) 2. What is Bravais lattice, what is basis and what is crystal lattice (Fig. 2). The differences between five possible Bravais lattices in two dimensions (Fi…