Java-文件操作和IO

文件介绍

文件本身有多重含义,狭义的文件,特指硬盘上的文件(以及保存文件的目录) ,广义的文件:计算机上的很多硬件设备,软件资源,在操作系统中,都会被视为是"文件"

文件除了有数据内容之外,还有一部分信息,例如文件名,文件类型,文件大小,这些信息可以称作文件的元信息

树型结构组织和目录

在一个电脑上,有很多文件,文件数量太多,所以要对文件进行系统管理,操作系统专门有一个模块-"文件系统 ",一般是通过"文件资源管理器"观察到文件系统管理的文件.

进行文件的组织,采用了层级结构 进行组织,也就是树型结构(n叉树) ,一种专门用来存放管理信息的特殊文件,即文件夹或者目录.

文件夹/目录 中保存的就是关于文件的元信息

文件路径

如何在文件系统中定位唯一一个文件呢?

从树型结构的角度来看,树中的每个结点都可以被一条从根开始,一直到达的结点的路径所描述,这种描述方式就称为文件的绝对路径

例:

C:\Intel\iGfx\Vulkan

除了可以从根开始进行路径的描述,我们可以从任意结点出发,进行路径的描述,这种描述方式就被称为相对路径

相对路径可以是以下几种形式:

  1. 相对于当前目录:使用文件名或目录名即可,不需要任何前缀。例如,如果当前目录是 "/home/user",要引用同一目录下的 "file.txt",可以使用相对路径 "file.txt"。
  2. 相对于上级目录:使用 "../" 表示上级目录。例如,要引用上级目录中的文件 "parentfile.txt",可以使用相对路径 "../parentfile.txt"。
  3. 相对于任意目录:使用若干个 "../" 组合表示相对于当前目录的某一级别的上级目录。例如,要引用当前目录的上一级目录的子目录 "subdir" 下的文件 "subfile.txt",可以使用相对路径 "../../subdir/subfile.txt"。

文件属性

即使是普通文件,根据其保存数据的不同,我们一般简单的划分为文本文件和二进制文件

  1. 文本文件: 文本文件是以文本形式存储数据的文件。它由字符组成,每个字符都使用特定的编码方式表示。常见的文本文件格式包括TXT、CSV等。文本文件可以使用文本编辑器打开,并且可以直接阅读和编辑其中的内容。文本文件中的数据通常是以行为单位进行组织,每行数据可以包含字母、数字、符号等。

  2. 二进制文件: 二进制文件是以二进制形式存储数据的文件。它不是以字符的形式存在,而是以字节的形式存储。二进制文件可以包含任意类型的数据,如图片、音频、视频、程序等。二进制文件的内容无法直接阅读或编辑,需要使用特定的程序或工具进行解析和处理。二进制文件通常是使用特定的格式进行编码和存储,如JPEG、MP3、EXE等。

区别:

  • 存储方式:文本文件以字符形式存储,二进制文件以字节形式存储。
  • 可读性:文本文件内容可以直接阅读和编辑,而二进制文件内容通常需要特定的工具进行解析和处理。
  • 文件大小:由于文本文件只存储字符,而二进制文件可以存储任意类型的数据,所以相同数据量下,二进制文件通常比文本文件更小。
  • 处理效率:由于文本文件内容可以直接读取和处理,所以在某些情况下,处理文本文件可能更加高效。

文件操作

Java操作文件,通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述.

1.文件系统操作

File类

属性
修饰符及类型 属性 说明
static String pathSeparator 依赖于系统的路径分隔符,String类型表示
static char pathSeparator 依赖于系统的路径分隔符,char类型的表示
构造方法
方法 说明
File(File parent,String child) 根据父目录+孩子文件路径,创建一个新的File实例
File(String pathname) 根据文件路径创建一个新的File实例,路径可以是绝对路径或者相对路径
File(String parent,String child) 根据父目录+孩子文件路径,创建一个新的File实例,父目录用路径表示
方法
修饰符及返回值类型 方法签名 说明
String getParent() 返回FIle对象的父目录文件路径
String getName() 返回File对象的纯文件名称
Strng getPath() 返回File对象的文件路径
String gerAbsolutePath() 返回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.获取文件相关信息

java 复制代码
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());
    }
    /**
     * 输出
     * .
     * text.txt
     * .\text.txt
     * D:\LXY_Java\javaa\Thread\.\text.txt
     * D:\LXY_Java\javaa\Thread\text.txt
     */

2.创建新文件:

java 复制代码
public static void main(String[] args) throws IOException {
        File file = new File("./test.txt");
        boolean ok = file.createNewFile();
        System.out.println(ok);
        System.out.println(file.exists());
        System.out.println(file.isFile());
        System.out.println(file.isDirectory());
    }
    /**
     * false
     * true
     * true
     * false
     */

3.删除文件:

java 复制代码
public static void main(String[] args) {
        File file = new File("./test.txt");
        boolean ok = file.delete();
        System.out.println(ok);
    }
    //true
public static void main(String[] args) {
        File file = new File("./test.txt");
        file.deleteOnExit();
        System.out.println("执行删除完毕");
        Scanner scanner = new Scanner(System.in);
        scanner.next();
    }

4.创建目录:

java 复制代码
public static void main(String[] args) {
        File f = new File("./abc/def/ghi");
        boolean ok = f.mkdirs();
        System.out.println(ok);
    }

5.重命名

java 复制代码
public static void main(String[] args) {
        File srcFile = new File("./abc/def");
        File destDile = new File("./aaa");
        boolean ok = srcFile.renameTo(destDile);
        System.out.println(ok);
    }

2.文件内容操作

数据流

数据流(Data Streams)是在程序中进行数据输入和输出的一种方式。数据流主要用于处理基本数据类型和对象的序列化和反序列化操作。

在Java中,数据流主要包括了两种类型:字节流和字符流

字节流(Byte Streams) 用于处理二进制数据 ,以字节(byte)为单位进行读取和写入。常见的字节流类有InputStream和OutputStream

字符流(Character Streams) 用于处理文本数据 ,以字符(char)为单位进行读取和写入。常见的字符流类有Reader和Writer

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 的步骤一般包括以下几步:

  1. 创建 InputStream 的子类对象,如 FileInputStream,用于打开要读取的文件。
  2. 调用 InputStream 对象的 read()、read(byte[] b)、read(byte[] b, int off, int len) 方法读取字节数据。
  3. 处理读取到的数据。
  4. 关闭 InputStream 对象,释放资源,使用 close() 方法。
FileInputStream
方法 说明
FileInputStream(File file) 利用File构造文件输入流
FileInputStream(String name) 利用文件路径构造文件输入流

利用Scanner进行字符读取

构造方法 说明
Scanner(InputStream is,String charset) 使用charset字符集进行is的扫描读取
示例

读取文件两种方式

上述图中

  • read():调用一次读一个字节
  • read(byte[] b,int off,int len):一次读取 b 中 [off,off+len)范围的区间
  • read(byte[] b):一次读取 b 中所有字节
java 复制代码
public static void main(String[] args) {
        try(InputStream inputStream = new FileInputStream("./test.txt")){
            while(true){
                int b = inputStream.read();
                if(b==-1){
                    //读取完毕
                    break;
                }
                //表示字节更习惯用16进制表现
                System.out.printf("0x%x\n",b);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
java 复制代码
public static void main(String[] args) {
        try(InputStream inputStream = new FileInputStream("./test.txt")){
            while(true){
                byte[] buffer  = new byte[1024];
                //n返回值表示read实际读取到
                int n = inputStream.read(buffer);
                if(n==-1){
                    break;
                }
                for (int i = 0; i < n; i++) {
                    System.out.printf("0x%x\n",buffer[i]);
                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

使用scanner

java 复制代码
public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("test.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() 刷新输出流的缓冲区,将缓冲区中的数据立即写入到输出目的地中,而不是等待缓冲区满或者流关闭

示例

java 复制代码
public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("./test.txt",true)){
            outputStream.write(0xe4);
            outputStream.write(0xbd);
            outputStream.write(0xa0);
            outputStream.write(0xe5);
            outputStream.write(0xa5);
            outputStream.write(0xbd);
            outputStream.flush();
        }  catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //hello

Reader和Writer

Reader和Writer与InputStream和OutputStream类似,区别就是Reader和Writer以字符(char)为单位进行读取和写入

java 复制代码
public static void main(String[] args) {
        try(Reader reader = new FileReader("./test.txt")){
            char[] buffer = new char[1024];
            int n = reader.read(buffer);
            System.out.println(n);
            for (int i = 0; i < n; i++) {
                System.out.println(buffer[i]);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
java 复制代码
public static void main(String[] args) {
        try(Writer writer = new FileWriter("./test.txt",true)){
            writer.write("你好世界");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
相关推荐
2401_8576100315 分钟前
Spring Boot框架:电商系统的技术优势
java·spring boot·后端
希忘auto31 分钟前
详解MySQL安装
java·mysql
娅娅梨33 分钟前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
汤米粥39 分钟前
小皮PHP连接数据库提示could not find driver
开发语言·php
冰淇淋烤布蕾42 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺1 小时前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
Jakarta EE1 小时前
正确使用primefaces的process和update
java·primefaces·jakarta ee
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法