gpt4 book ai didi

java - 有没有一种聪明的方法来编写固定长度的平面文件?

转载 作者:搜寻专家 更新时间:2023-10-30 21:21:01 26 4
gpt4 key购买 nike

是否有任何框架/库可以帮助在 java 中编写固定长度的平面文件?

我想将 bean/实体的集合写入一个平面文件,而不用担心转换、填充、对齐、填充等

例如,我想像这样解析一个 bean:

public class Entity{
String name = "name"; // length = 10; align left; fill with spaces
Integer id = 123; // length = 5; align left; fill with spaces
Integer serial = 321 // length = 5; align to right; fill with '0'
Date register = new Date();// length = 8; convert to yyyyMMdd
}

...进入...

name      123  0032120110505
mikhas 5000 0122120110504
superuser 1 0000120101231

...

最佳答案

您不太可能遇到可以处理“遗留”系统格式的框架。在大多数情况下,遗留系统不使用标准格式,但框架需要它们。作为遗留 COBOL 系统和 Java/Groovy 转换的维护者,我经常遇到这种不匹配的情况。 “担心转换、填充、对齐、填充等”是您在处理遗留系统时主要要做的事情。当然,您可以将其中的一些封装到方便的助手中。但最有可能的是,您需要真正熟悉 java.util.Formatter。

例如,您可以使用装饰器模式创建装饰器来进行转换。下面是一些 groovy(很容易转换成 Java):

class Entity{
String name = "name"; // length = 10; align left; fill with spaces
Integer id = 123; // length = 5; align left; fill with spaces
Integer serial = 321 // length = 5; align to right; fill with '0'
Date register = new Date();// length = 8; convert to yyyyMMdd
}

class EntityLegacyDecorator {
Entity d
EntityLegacyDecorator(Entity d) { this.d = d }

String asRecord() {
return String.format('%-10s%-5d%05d%tY%<tm%<td',
d.name,d.id,d.serial,d.register)
}
}

def e = new Entity(name: 'name', id: 123, serial: 321, register: new Date('2011/05/06'))

assert new EntityLegacyDecorator(e).asRecord() == 'name 123 0032120110506'

如果您没有太多这些对象并且对象不是太复杂,这是可行的。但是很快格式字符串就变得无法忍受了。然后你可能需要 Date 的装饰器,比如:

class DateYMD {
Date d
DateYMD(d) { this.d = d }
String toString() { return d.format('yyyyMMdd') }
}

所以你可以用 %s 格式化:

    String asRecord() {
return String.format('%-10s%-5d%05d%s',
d.name,d.id,d.serial,new DateYMD(d.register))
}

但是对于大量的 bean 属性,字符串仍然太粗糙,所以您想要一些能够理解列和长度的东西,看起来像您收到的 COBOL 规范,所以您将编写如下内容:

 class RecordBuilder {

final StringBuilder record

RecordBuilder(recordSize) {
record = new StringBuilder(recordSize)
record.setLength(recordSize)
}

def setField(pos,length,String s) {
record.replace(pos - 1, pos + length, s.padRight(length))
}

def setField(pos,length,Date d) {
setField(pos,length, new DateYMD(d).toString())
}

def setField(pos,length, Integer i, boolean padded) {
if (padded)
setField(pos,length, String.format("%0" + length + "d",i))
else
setField(pos,length, String.format("%-" + length + "d",i))
}

String toString() { record.toString() }
}

class EntityLegacyDecorator {

Entity d

EntityLegacyDecorator(Entity d) { this.d = d }

String asRecord() {
RecordBuilder record = new RecordBuilder(28)
record.setField(1,10,d.name)
record.setField(11,5,d.id,false)
record.setField(16,5,d.serial,true)
record.setField(21,8,d.register)
return record.toString()
}

}

在您编写了足够多的 setField() 方法来处理遗留系统后,您将简要考虑将其作为“框架”发布到 GitHub 上,这样下一个可怜的 sap 就不必再使用它了。但是随后您将考虑您看到的 COBOL 存储“日期”(MMDDYY、YYMMDD、YYDDD、YYYYDDD)和数字(假定十进制、显式小数、符号作为尾随分隔符或符号作为前导 float 字符)的所有荒谬方式。然后你会意识到为什么没有人为此制作一个好的框架,并且偶尔将你的生产代码的一些部分作为示例发布到 SO 中......;)

关于java - 有没有一种聪明的方法来编写固定长度的平面文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5885063/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com