【✺网络编程】Java IO读写文本文件

下面主要使用的是 FileOutputStream / FileInputStream 把 IO 流绑定到 File 对象上,然后将这两个字节流通过OutputStreamReader / InputStreamReader 转换为字符流,并设置字符编码,最后再用 PrintWriter / BufferedReader 给字节流增加缓冲功能,让程序能更方便地以行为单位操作 IO 流。

写文件示例程序

这个例子里我们运行程序后,Java 程序会在命令行界面等待用户的输入,先让用户从命令行界面输入想要保存内容的文件的名字,再让用户输入内容。内容支持多行输入,直到遇到空行,程序会认为输入完毕,然后 Java 用用户指定的名字在项目目录下创建一个文件,最后把程序读取到的所有内容输入,写到文件里去。

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class WriteToFilesAppMain {

    private static final Scanner in = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        File targetFile = createFile();

        writeToFile(targetFile);

        System.out.println("程序执行结束");

    }

    private static void writeToFile(File targetFile) throws IOException {
        // 使用 try with resource 自动回收打开的资源
        try (
                // 创建一个OutputStream 建立一个从程序到文件的byte数据传输流
                FileOutputStream fos = new FileOutputStream(targetFile);
                // 创建一个可以使用OutputStream的Writer,并制定字符集,这样程序就能一个一个字符地写入
                OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
                // 使用PrintWriter, 可以方便的写入一行字符
                PrintWriter pw = new PrintWriter(osw);
        ) {
            System.out.println("输入的内容会实时写入文件,如果输入空行则结束");
            while (true) {
                String lineToWrite = in.nextLine().trim();
                System.out.println("输入内容为:" + lineToWrite);
                if (lineToWrite == null || lineToWrite.equals("")) {
                    System.out.println("输入结束");
                    break;
                } else {
                    pw.println(lineToWrite);
                    // 真正用的时候不要写一行就flush() 这里只是演示
                    pw.flush();
                }
            }
            // 平时用的时候放在外面 flush
            // pw.flush();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private static File createFile() throws IOException {
        System.out.println("请输入文件名:");
        String fileName = in.nextLine().trim();
        File f = new File("." + File.separator + fileName + ".txt");
        if (f.isFile()) {
            System.out.println("目标文件存在,删除:" + f.delete());
        }
        System.out.println(f.createNewFile());
        return f;
    }
}

这个示例程序里我们需要重点关注以下几个方面的知识点:

  • 上面例程里使用了Scanner,以命令行交互的方式让我们能输入程序将要创建文件的名称和要往文件里写入的内容。
  • Java 的 IO流在使用完成后需要统一调用close()方法把流关闭掉。IO流的关闭会让程序释放出它们占用的内存资源,而且字符流操作时使用了缓冲区,并在关闭字符流时会强制将缓冲区内容输出,如果不关闭流,则缓冲区的内容是无法输出的。
  • 如果想在不关闭流时,就将缓冲区的内容输出到文件,可以调用流的flush()方法强制清空流使用的缓冲区。
  • 上面的示例程序里我们使用了try-with-resource形式的异常处理,把资源的关闭交给了Java– 在资源被使用完成后或者程序出现异常终止执行时都会由 Java 自动关闭在try-with-resource中打开的流资源。
  • 把字符串内容写入到文件的程序中,我们首先使用了 FileOutputStream 把目标文件绑定到字节输出流,再用 OutputStreamWriter 创建一个可以使用OutputStream的Writer,并指定其字符集为UTF_8,这样程序就能一个字符一个字符地写入文件啦。
  • 接下来程序在OutputStreamWriter 字符流的基础上创建了 PrintWriter,使用 PrintWriter 可以让程序方便地写入字符串,并且也可以通过它的 println 方法来自动处理换行符。

用 Java 程序完成文件的写入操作后,我们再来看看,给定一个文件,怎么用 Java 程序读取器中的内容。

读文本示例程序

添加一个测试用的名为 file.txt 的文本文件,创建好文件后,在文件里随便输入几行内容用于测试:

aaa
一二三
bbb
四五六
ccc
七八九
ddd
锟斤拷
烫烫屯屯

接下来我们用 Java 程序读取这个文件里的内容,这次我们则是会用到 IO 输入流相关的几个类: FileInputStream, InputStreamReader, BufferedReader等;它们的具体功能作用我写在了程序的注释里

import java.io.*;
import java.nio.charset.StandardCharsets;

public class ReadStringFromFileAppMain {
    private static final String SOURCE_FILE_NAME = "file.txt";

    public static void main(String[] args) {

        File sourceFile = new File("." + File.separator + SOURCE_FILE_NAME);

        readLineFromFile(sourceFile);
    }

    private static void readLineFromFile(File sourceFile) {
        try (
                // 建立从文件到程序的数据输入(input)流
                FileInputStream fis = new FileInputStream(sourceFile);
                // 用 InputStreamReader 包装 byte流,并指定字符编码,让它能够将读出的byte转为字符
                InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
                //  增加缓冲功能,输入输出效率更高,并且可以一次读一行
                BufferedReader reader = new BufferedReader(isr)
        ) {
            String line = null;
            while ((line = reader.readLine()) != null) {
                System.out.println(line.trim().toUpperCase());
            }
            // 还可以从reader里获取 Stream,然后通过流操作+Lambda的形式完成
            // reader.lines().map(String::trim).map(String::toUpperCase).forEach(System.out::println);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

上面这个示例程序会用 Java 的 IO 输入流从文件中每次读取一行,并把行内容应用 toUpperCase() 方法后输出到终端,程序里打开的流资源的方式仍然是交给try-with-resource机制自动处理。

输出流一样,在读取文件内容的程序中我们也做了字节流到字符流的转换,先用 FileInputStream 把文件绑定到了字节流上,然后通过 InputStreamReader 把字节流转换为字符流,在这个过程中也是设置了字符编码,最后又用 BufferedReader 为字符流增加缓冲功能,这样读取的效率会更高一些,通过它程序可以一次读取文件的一整行。

通过 BufferedReader 的 readLine()遍历或者 lines() 获取Stream 后进行流处理,都可以用 BufferedReader 完成文件内容的遍历读取,上面在程序代码和注释里我们演示了两种遍历 BufferedReader 的方法。

posted @   残城碎梦  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示