Java IO 教程

Java IO 文件(File)

文件是 Java 应用程序中常见的数据源或目的地。因此,本文将简要介绍如何在 Java 中处理文件。我们无意在此详细解释每种技术,而是希望为你提供足够的知识来决定文件访问方法。

Java IO 文件相关类

Java IO API 包含以下与在 Java 中处理文件有关的类:

  • File:表示文件或目录的抽象路径名。

  • RandomAccessFile:支持随机读写文件的类。

  • FileInputStream:用于从文件读取字节的流。

  • FileReader:用于从文件读取字符的流。

  • FileOutputStream:用于向文件写入字节的流。

  • FileWriter:用于向文件写入字符的流。

下文将简要介绍这些类。

API 文档地址:https://docs.oracle.com/javase/8/docs/api/java/io/package-summary.html 

通过 Java IO 读取文件

如果需要读取文件内容,可以使用 FileInputStream FileReader 类。具体选择哪一个,取决于你想读取的是二进制数据还是文本数据。这两个类可以让你从文件中一次读取一个字节(byte)或字符(char),或者将字节/字符读入到一个字节/字符数组。

注意,这两个类读取文件必须从文件开头,逐一读取到文件末尾,不能随机读取。如下图:

image.png

其实,你可以将文件内容想象成一个大的字节或字符数组,我们读取文件时只能从下标为 0 的位置开始遍历。

示例:

package com.hxstrive.java_io.inputstream;

import java.io.FileInputStream;

/**
* 读取文件示例
* @author hxstrive.com
*/
public class FileInputStreamDemo1 {

   public static void main(String[] args) {
       try(FileInputStream fileInputStream = new FileInputStream("D:\\input.txt")) {
           byte[] bytes = new byte[fileInputStream.available()];
           int len = fileInputStream.read(bytes);
           System.out.println(len); // 13
           System.out.println(new String(bytes)); // Hello Java IO
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

}

如果需要在文件中跳转(即跳过 N 个字节或字符),只从这里或那里读取部分内容,可以使用 RandomAccessFile(随机读取文件类)。

通过 Java IO 写入文件

如果需要将数据写入文件,可以使用 FileOutputStream FileWriter 类,具体选择哪一个类取决于需要写入的是二进制数据还是字符。你可以每次写入一个字节(byte)或字符(char),也可以写入字节和字符数组。

注意:

(1)数据会按照写入的顺序依次存储在文件中。

(2)仅支持从文件开头一次写入到文件末尾,不能随机将字节或字符写入到文件中指定的位置。

示例:

package com.hxstrive.java_io.outputstream;

import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
* 写文件示例
* @author hxstrive.com
*/
public class FileOutputStreamDemo {

   public static void main(String[] args) {
       try(FileOutputStream output = new FileOutputStream("D:\\output.txt");
           FileInputStream input = new FileInputStream("D:\\output.txt")) {

           // 写出数据
           output.write("Hello World!".getBytes());
           output.flush();

           // 读取数据
           byte[] buffer = new byte[1024];
           int len = input.read(buffer);
           System.out.println(new String(buffer, 0, len)); // Hello World!

       } catch (Exception e) {
           e.printStackTrace();
       }
   }

}

如果需要跳过文件并在不同位置写入数据,例如追加到文件末尾,可以使用 RandomAccessFile

通过 Java IO 实现对文件的随机访问

如前所述,你可以通过 RandomAccessFile 类使用 Java IO 随机访问文件。

随机存取并不意味着可以从真正随机的地方读取或写入。它只是意味着你可以跳过文件,以任何你想要的方式同时读取或写入文件。这就是“随机”的含义 —— 下一个字节的读取并不取决于前一个字节的读取,不强制执行特定的访问顺序。你可以 “随机”—— 任意地访问文件中的字节。这样,就可以覆盖现有文件的某些部分、向文件添加内容、删除文件,当然也可以从需要读取文件的地方读取文件。

如下图,从文件两个位置读取内容,先从文件末尾读取“位置1”对应的内容,然后再次从文件“位置2”读取对应的内容:

image.png

示例:

package com.hxstrive.java_io.other;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
* 随机访问文件
* @author hxstrive
*/
public class RandomAccessFileDemo {
   public static void main(String[] args) {
       String fileName = "D:\\random.txt";
       try (RandomAccessFile file = new RandomAccessFile(fileName, "rw")) {
           // 写入数据
           file.writeUTF("Hello, World!");
           // 将文件指针移到文件开头
           file.seek(0);
           // 读取数据
           System.out.println("读取的数据: " + file.readUTF()); // 读取的数据: Hello, World!

           // 修改数据
           file.seek(7); // 将文件指针移到第 8 个字符的位置
           file.writeUTF("Java");
           // 将文件指针移到文件开头
           file.seek(0);
           // 再次读取数据
           System.out.println("修改后的数据: " + file.readUTF()); // 修改后的数据: Hello Javad!
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}

文件和目录信息访问

有时,你可能需要访问文件的相关信息而不是其内容。例如,你需要知道文件大小或文件属性。目录的情况也是如此。例如,你可能想获得一个给定目录中所有文件的列表。文件和目录信息都可以通过文件类获取。

示例:

package com.hxstrive.java_io.file;

import java.io.File;

/**
* 获取文件基本信息
* @author hxstrive.com
*/
public class FileDemo {

   public static void main(String[] args) {
       File file = new File("D:\\input.txt");
       System.out.println("文件名:" + file.getName()); // 文件名:input.txt
       System.out.println("文件路径:" + file.getPath()); // 文件路径:D:\input.txt
       System.out.println("存在?" + file.exists()); // 存在?true
       System.out.println("是文件?" + file.isFile()); // 是文件?true
       System.out.println("是目录?" + file.isDirectory()); // 是目录?false
       System.out.println("文件长度:" + file.length()); // 文件长度:13
       System.out.println("最后修改日期:" + file.lastModified()); // 最后修改日期:1735194454080
       System.out.println("能读?" + file.canRead()); // 能读?true
       System.out.println("能写?" + file.canWrite()); // 能写?true
       System.out.println("能执行?" + file.canExecute()); // 能执行?true
   }

}

递归访问一个目录下面所有到文件,例如:

package com.hxstrive.java_io.file;

import java.io.File;
import java.util.Objects;

/**
 * 递归遍历目录
 * @author hxstrive.com
 */
public class FileDemo2 {

    public static void main(String[] args) {
        File file = new File("D:\\demo");
        if(!file.isDirectory()) {
            // 不是目录
            System.out.println(file.getAbsoluteFile());
            return;
        }

        // 是目录
        File[] files = file.listFiles();
        if(Objects.nonNull(files)) {
            show(file);
        }
    }

    /**
     * 递归显示目录内容
     * @param file 文件/目录
     */
    private static void show(File file) {
        if(file.isDirectory()) {
            File[] files = file.listFiles();
            if(Objects.nonNull(files)) {
                for(File f : files) {
                    if(f.isDirectory()) {
                        System.out.println(f.getAbsoluteFile());
                        show(f);
                    } else {
                        System.out.println(f.getAbsoluteFile());
                    }
                }
            }
        } else {
            System.out.println(file.getAbsoluteFile());
        }
    }

}

使用 tree D:/demo /F /A 命令查看 demo 目录到结构,如下图:

image.png

运行结果如下:

D:\demo\c++
D:\demo\c++\Hello.c
D:\demo\Hello.java
D:\demo\java
D:\demo\java\network
D:\demo\java\network\Echo.java
D:\demo\java\Test.java

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号