Hutool工具类关于FileReader文件读取的见解

本文深入解析了Hutool库中FileReader类的工作原理,展示了如何使用它轻松读取JSON文件并转换为字符串,涉及FileReader构造函数、readString方法及内部实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件读取-FileReader

有需求是读取 json 文件并导出excel,由于用到了 FileReader, 体会到其强大的读取文件的能力。所以深入源码理解其原理。

FileReader fileReader = new FileReader(filename);
String fileContent = fileReader.readString();

简单的两行代码就能实现读取文件并转换为 String, 何其强大。

先来看看 FileReader 的构造函数

public FileReader(String filePath) {
    this(filePath, DEFAULT_CHARSET);
}

public FileReader(String filePath, Charset charset) {
    //这里其实调用的是 java.io.File
    this(FileUtil.file(filePath), charset);
}

public FileReader(File file, Charset charset) {
    //super方法这里调用类 FileWrapper 构造方法
    super(file, charset);
    //检查是否为 文件
    this.checkFile();
}

FileWrapper 构造方法

public FileWrapper(File file, Charset charset) {
    this.file = file;
    this.charset = charset;
}

FileReader 继承自 FileWrapper

package cn.hutool.core.io.file;

public class FileReader extends FileWrapper

FileWrapper 类中的属性

public class FileWrapper implements Serializable {
    private static final long serialVersionUID = 1L;
    protected File file;
    protected Charset charset;
    public static final Charset DEFAULT_CHARSET;
    
    //...
}

查看 readString 会发现

//FileReader类

public String readString() throws IORuntimeException {
    //这个 String 是调用 java.lang.String,将字节数组转为字符的过程
    return new String(this.readBytes(), this.charset);
}

readBytes(),其实是将 file 转换为 byte[] 的过程

public byte[] readBytes() throws IORuntimeException {
        long len = this.file.length();
        if (len >= 2147483647L) {
            throw new IORuntimeException("File is larger then max array size");
        } else {
            byte[] bytes = new byte[(int)len];
            FileInputStream in = null;

            try {
                in = new FileInputStream(this.file);
                //file 转为 byte[]
                int readLength = in.read(bytes);
                if ((long)readLength < len) {
                    throw new IOException(StrUtil.format("File length is [{}] but read [{}]!", new Object[]{len, readLength}));
                }
            } catch (Exception var10) {
                throw new IORuntimeException(var10);
            } finally {
                IoUtil.close(in);
            }

            return bytes;
        }
    }

java.lang.String

public String(byte bytes[], Charset charset) {
    this(bytes, 0, bytes.length, charset);
}

public String(byte bytes[], int offset, int length, Charset charset) {
    if (charset == null)
        throw new NullPointerException("charset");
    checkBounds(bytes, offset, length);
    //StringCoding.decode 解码,将字节转为字符的过程
    this.value =  StringCoding.decode(charset, bytes, offset, length);
}

未完待续…

<think>我们被要求使用Hutool工具类实现两个功能:按照行读取文件,以及使用JSONUtil处理JSON。根据用户的问题,重点在于如何按照行读取文件,并且用户提到了JSONUtil,但问题中并没有要求将文件内容作为JSON处理,而是按照行读取。引用[2]中展示了使用FileUtil.readString读取整个文件内容,但没有按行读取的示例。引用[3]提到了IoUtil,其中有一个方法readObj,但按行读取通常用readLines方法。Hutool提供了FileUtil.readLines方法可以按行读取文件。但是,用户特别提到了JSONUtil,而问题中要求按照行读取文件,这似乎与JSONUtil无关。因此,我们可能只需要使用FileUtil.readLines来实现按行读取。然而,用户问的是“使用Hutool工具类中的JSONUtil按照行读取文件”,这看起来有些矛盾,因为JSONUtil通常用于JSON转换,而不是按行读取文件。分析问题:用户可能误解了,或者有两个需求:一是按行读取文件,二是使用JSONUtil处理某些JSON数据。但问题描述中只有按行读取文件的需求。因此,我们应回答按行读取文件的方法,并澄清JSONUtil的作用。步骤:1.澄清JSONUtil的作用:它用于对象和JSON字符串之间的转换,不用于文件按行读取。2.提供使用Hutool按行读取文件的方法:使用FileUtil.readLines方法。从引用[3]中我们得知Hutool有IoUtil,但实际按行读取在FileUtil中也有提供。示例代码(参考引用[2]的风格):使用FileUtil.readLines方法,它返回一个List<String>,每一行作为列表的一个元素。注意:用户要求按照行读取,因此我们使用readLines。代码示例:引用[4]中提到了Hutool提供了文件操作等功能,所以我们可以使用FileUtil。所以,按照行读取文件的代码可以这样写:```javaimportcn.hutool.core.io.FileUtil;importjava.util.List;publicclassReadFileByLine{publicstaticvoidmain(String[]args){//文件路径StringfilePath="test.txt";//按行读取文件,返回一个字符串列表List<String>lines=FileUtil.readLines(filePath,"UTF-8");//遍历打印每一行for(Stringline:lines){System.out.println(line);}}}```另外,如果用户想用JSONUtil来处理读取到的某一行(比如某一行是JSON字符串),那么我们可以先按行读取,然后对需要转换的行使用JSONUtil。例如,如果文件每一行都是一个JSON字符串,我们可以这样处理:```javaimportcn.hutool.core.io.FileUtil;importcn.hutool.json.JSONUtil;importjava.util.List;publicclassReadJsonLines{publicstaticvoidmain(String[]args){//文件路径StringfilePath="test.json";//按行读取文件List<String>lines=FileUtil.readLines(filePath,"UTF-8");//遍历每一行,将每一行的JSON字符串转换为对象for(StringjsonLine:lines){//假设每一行是一个User对象的JSON字符串Useruser=JSONUtil.toBean(jsonLine,User.class);System.out.println(user);}}}classUser{privateStringname;privateintage;//省略构造方法和getter/setter}```但注意:用户的问题中只要求按行读取,并没有提到要解析JSON。所以我们首先提供按行读取的方法。总结回答:1.说明JSONUtil的作用:用于JSON转换,不能直接按行读取文件。2.按行读取文件应该使用FileUtil.readLines方法。3.如果需要将每一行当作JSON处理,再结合JSONUtil进行转换。根据以上分析,我们生成回答。</think> ### 如何用 Hutool 实现按行读取文件并处理 JSON 根据您的需求,您需要使用 **Hutool 的 `FileUtil` 工具类**实现按行读取文件,而非 `JSONUtil`(后者用于 JSON 数据转换)。以下是完整实现方案: --- ### 1. 按行读取文件核心方法(使用 `FileUtil`) ```java import cn.hutool.core.io.FileUtil; import java.util.List; public class FileLineReader { public static void main(String[] args) { // 1. 指定文件路径和编码 String filePath = "test.txt"; String charset = "UTF-8"; // 2. 按行读取文件内容 → 返回字符串列表 List<String> lines = FileUtil.readLines(filePath, charset); // 3. 逐行处理内容 for (String line : lines) { System.out.println("行内容: " + line); // 此处可添加JSON处理逻辑(见第2部分) } } } ``` --- ### 2. 配合 `JSONUtil` 处理 JSON 数据 如果文件中每行是 JSON 字符串,可结合 `JSONUtil` 解析: ```java import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; // 在逐行循环内添加: if (JSONUtil.isTypeJSON(line)) { // 解析单行JSON JSONObject jsonObj = JSONUtil.parseObj(line); System.out.println("解析JSON: " + jsonObj); // 提取具体字段(示例) String name = jsonObj.getStr("name"); Integer age = jsonObj.getInt("age"); } ``` --- ### 关键说明 1. **正确工具类选择** - 📍 按行读取 → `FileUtil.readLines()`(引用[2]) - 📍 JSON 转换 → `JSONUtil.toBean()`(引用[1]) - 🚫 `JSONUtil` **不能**直接读取文件,需先获取文本内容[^1][^2] 2. **性能优化建议** ```java // 大文件使用迭代器避免内存溢出 FileReader fileReader = FileUtil.getReader(filePath, charset); fileReader.readLines().forEach(line -> { // 逐行处理逻辑 }); ``` --- ### 场景示例 假设 `data.jsonl` 内容为: ```json {"name":"张三","age":25} {"name":"李四","age":30} ``` 处理代码: ```java List<String> lines = FileUtil.readLines("data.jsonl", "UTF-8"); lines.forEach(line -> { User user = JSONUtil.toBean(line, User.class); // 转换为Java对象 System.out.println(user.getName()); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值