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

如何通过FlatPack在Java中读取无分隔符文本文件

嘿,刚好我用过FlatPack处理过这类固定宽度无分隔符的文本文件,给你一步步拆解怎么实现,完美匹配你要的类型转换需求!

用FlatPack解析固定宽度文本文件的完整步骤

1. 先引入FlatPack依赖

如果你的项目用Maven,直接在pom.xml里加这个依赖(用最新稳定版就行):

<dependency>
    <groupId>net.sf.flatpack</groupId>
    <artifactId>flatpack</artifactId>
    <version>3.4.0</version>
</dependency>

Gradle项目对应调整依赖配置即可。

2. 编写字段映射XML文件(核心!)

FlatPack靠这个XML文件识别每个字段的位置、宽度和类型。首先你得先确定每个字段的固定宽度——根据你的示例数据,我梳理了大致的字段宽度(你可以根据实际文件微调):

  • Prod Name: 8字符(比如samsungA是7个字符,后面补1个空格)
  • City: 11字符(比如London后面补5个空格,California后面补1个空格)
  • Price: 4字符(6500、3500这类都是4位)
  • zipcode: 5字符(14021这类5位)
  • Date: 10字符(10/07/2018这种格式刚好10位)

然后创建一个product_mapping.xml文件,内容如下:

<?xml version="1.0"?>
<!DOCTYPE PZMAP SYSTEM "http://flatpack.sourceforge.net/dtd/pzmap.dtd">
<PZMAP>
    <RECORD name="ProductData">
        <!-- start从1开始计数,length是字段宽度,type指定转换类型 -->
        <COLUMN name="ProdName" start="1" length="8" type="STRING"/>
        <COLUMN name="City" start="9" length="11" type="STRING"/>
        <COLUMN name="Price" start="20" length="4" type="INTEGER"/>
        <COLUMN name="Zipcode" start="24" length="5" type="INTEGER"/>
        <COLUMN name="Date" start="29" length="10" type="DATE" format="dd/MM/yyyy"/>
    </RECORD>
</PZMAP>

重点说明:

  • start:字段在每行的起始位置(从1开始计数)
  • length:字段的固定字符数
  • type:FlatPack支持自动转换的类型,比如STRING、INTEGER、DATE
  • 日期类型必须加format,要和文件里的日期格式完全匹配

3. 编写Java解析代码

接下来写代码读取文件、解析并转换类型,直接上可运行的示例:

import net.sf.flatpack.DataSet;
import net.sf.flatpack.DefaultParserFactory;
import net.sf.flatpack.Parser;
import net.sf.flatpack.ParserFactory;

import java.io.FileReader;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FixedWidthFileReader {
    public static void main(String[] args) {
        try {
            // 1. 加载映射文件,创建固定宽度解析器
            ParserFactory parserFactory = DefaultParserFactory.getInstance();
            Parser parser = parserFactory.newFixedLengthParser(new FileReader("product_mapping.xml"));
            
            // 2. 指定要解析的文本文件
            parser.setDataSource(new FileReader("your_data_file.txt"));
            
            // 3. 跳过第一行的表头(如果你的文件第一行是表头的话)
            parser.skip(1);
            
            // 4. 解析数据成DataSet
            DataSet dataSet = parser.parse();
            
            // 5. 迭代每条数据,获取转换后的字段
            while (dataSet.next()) {
                String prodName = dataSet.getString("ProdName").trim(); // 去掉可能的末尾空格
                String city = dataSet.getString("City").trim();
                int price = dataSet.getInt("Price");
                int zipcode = dataSet.getInt("Zipcode");
                Date date = dataSet.getDate("Date");
                
                // 这里可以把数据存入实体类、数据库,或者直接打印验证
                System.out.printf(
                    "产品名: %s | 城市: %s | 价格: %d | 邮编: %d | 日期: %s%n",
                    prodName,
                    city,
                    price,
                    zipcode,
                    new SimpleDateFormat("dd/MM/yyyy").format(date)
                );
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 实际项目中建议用日志框架记录异常,方便排查
        }
    }
}

4. 关键注意事项

  • 字段宽度一定要准确:这是固定宽度解析的核心,你可以用Notepad++这类编辑器打开文件,光标定位到字段首尾,数清楚字符数(包括填充的空格)。
  • 处理多余空格:固定宽度文件通常会用空格填充字段,所以获取字符串字段后记得用trim()去掉前后空格。
  • 日期格式匹配:映射文件里的format必须和文件中的日期格式完全一致,比如如果文件里是MM/dd/yyyy,就要改成对应的格式。
  • 异常处理:实际项目中不要直接打印栈轨迹,最好用日志框架记录异常信息,方便后续排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:50:08