You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读写含单行与多行字符串的列表至文件(无分隔符方案)

可行方案汇总

除了JSON之外,你可以考虑以下几种无需分隔符或预统计行号的方案:

1. 字节长度前缀方案

通过在每个字符串前写入其UTF-8编码的字节长度,读取时先解析长度再读取对应字节数的内容,完全避免用户输入内容的干扰。

存储实现:

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

public static void storeToFile(List<String> strings, String fileName) throws IOException {
    try (FileOutputStream fos = new FileOutputStream(fileName)) {
        for (String s : strings) {
            byte[] contentBytes = s.getBytes(StandardCharsets.UTF_8);
            // 写入长度(数字字符串+换行)
            String lengthStr = String.valueOf(contentBytes.length) + "\n";
            fos.write(lengthStr.getBytes(StandardCharsets.UTF_8));
            // 写入字符串内容字节
            fos.write(contentBytes);
        }
    }
}

读取实现:

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public static List<String> fromFile(String fileName) throws IOException {
    List<String> result = new ArrayList<>();
    try (FileInputStream fis = new FileInputStream(fileName)) {
        ByteArrayOutputStream lengthBuffer = new ByteArrayOutputStream();
        int byteRead;
        while ((byteRead = fis.read()) != -1) {
            if (byteRead == '\n') {
                // 解析长度
                int contentLength = Integer.parseInt(new String(lengthBuffer.toByteArray(), StandardCharsets.UTF_8));
                lengthBuffer.reset();
                // 读取对应长度的内容字节
                byte[] contentBytes = new byte[contentLength];
                int actualRead = fis.read(contentBytes);
                if (actualRead != contentLength) {
                    throw new IOException("文件读取异常:未读取到预期长度的内容");
                }
                result.add(new String(contentBytes, StandardCharsets.UTF_8));
            } else {
                lengthBuffer.write(byteRead);
            }
        }
    }
    return result;
}

2. 转义+空行分隔方案

将字符串中的换行符转义为\n、反斜杠转义为\\,确保每个转义后的字符串都是单行,再用空行作为字符串分隔符(用户输入的内容转义后不会产生空行,因此安全)。

存储实现:

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;

public static void storeToFile(List<String> strings, String fileName) throws IOException {
    try (BufferedWriter writer = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8))) {
        for (int i = 0; i < strings.size(); i++) {
            String s = strings.get(i);
            // 先转义反斜杠,再转义换行符
            String escaped = s.replace("\\", "\\\\").replace("\n", "\\n");
            writer.write(escaped);
            // 非最后一个字符串后添加空行分隔
            if (i != strings.size() - 1) {
                writer.newLine();
                writer.newLine();
            }
        }
    }
}

读取实现:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public static List<String> fromFile(String fileName) throws IOException {
    List<String> result = new ArrayList<>();
    try (BufferedReader reader = new BufferedReader(
            new InputStreamReader(new FileInputStream(fileName), StandardCharsets.UTF_8))) {
        StringBuilder contentBuilder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.isEmpty()) {
                // 遇到空行,处理当前字符串
                if (contentBuilder.length() > 0) {
                    String unescaped = contentBuilder.toString().replace("\\n", "\n").replace("\\\\", "\\");
                    result.add(unescaped);
                    contentBuilder.setLength(0);
                }
            } else {
                contentBuilder.append(line);
            }
        }
        // 处理最后一个字符串
        if (contentBuilder.length() > 0) {
            String unescaped = contentBuilder.toString().replace("\\n", "\n").replace("\\\\", "\\");
            result.add(unescaped);
        }
    }
    return result;
}

3. Java对象序列化方案

直接使用Java内置的序列化机制,将整个List<String>写入二进制文件,读取时反序列化即可。优点是代码极简,缺点是文件不可读。

存储实现:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.List;

public static void storeToFile(List<String> strings, String fileName) throws IOException {
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
        oos.writeObject(strings);
    }
}

读取实现:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;

@SuppressWarnings("unchecked")
public static List<String> fromFile(String fileName) throws IOException, ClassNotFoundException {
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
        return (List<String>) ois.readObject();
    }
}

4. YAML格式方案

利用YAML对多行字符串的原生支持,通过第三方库(如SnakeYAML)实现列表的序列化和反序列化,文件可读性强。

存储实现(需引入SnakeYAML依赖):

import org.yaml.snakeyaml.Yaml;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

public static void storeToFile(List<String> strings, String fileName) throws IOException {
    Yaml yaml = new Yaml();
    try (FileWriter writer = new FileWriter(fileName, StandardCharsets.UTF_8)) {
        yaml.dump(strings, writer);
    }
}

读取实现:

import org.yaml.snakeyaml.Yaml;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

public static List<String> fromFile(String fileName) throws IOException {
    Yaml yaml = new Yaml();
    try (FileReader reader = new FileReader(fileName, StandardCharsets.UTF_8)) {
        return yaml.load(reader);
    }
}

内容的提问来源于stack exchange,提问作者moon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 22:51:11