固定宽度
具有流式支持和灵活选项的固定宽度文件格式工具集.
特征
- 弹性: 很多选项
- 零依赖关系:小脚印
- 本地流源支持
- 测试的很好: 密码覆盖率超过90%
- 支持大数据集: 生产准备就绪
- 本地无害环境管理支助: 未来证明
- 类型脚本支持
固定宽度文件格式
固定宽度文件格式是一种在文件中存储数据的简单方法. 分隔符会分行(一般为新行字符),而所有字段在行上都有固定的宽度.
这种格式在没有任何解析程序的情况下可以直接从文件中查找数据,但它没有压缩机制. 这个限制会导致内存(RAM和磁盘)的过度使用,与其他文件格式(如JSON或XML)一起存储相同的数据.
但是,在这一年[此处插入本年] A.D.,仍然可以找到使用这种文件格式的人. 别害怕,我的朋友! 此 Node.js 库将提供一个工具盘来解析和生成固定宽度的文件 .
示例文件
下一节将包含一个带两个字段的固定宽度数据示例:用户名和年龄. 第一个字段的宽度为12个字符,第二个字段的宽度为3个字符的正对相.
username age
alice 024
bob 030
安装
npm i @evologi/fixed-width
使用量
import { parse, stringify, Parser, Stringifier } from '@evologi/fixed-width'
parse(input, options)
它将文本或缓冲解为一系列元素。 如果它收到缓冲字符串 它返回所有解析项的数组。 它会收到可执行的(可能是) async),返回已输入的同类型可移动输入.
input<String> | <Buffer> | <Iterable> | <AsyncIterable>原始数据来分析.options<Object>见 选项一节。 。 。 .- 回返情况:
<Array> | <Iterable> | <AsyncIterable>
import { parse } from '@evologi/fixed-width'
const text = 'alice 024\nbob 030\n'
const users = parse(text, {
eol: '\n',
fields: [
{
property: 'username',
width: 12
},
{
cast: value => parseInt(value, 10),
property: 'age',
width: 3
}
]
})
// [{ username: 'alice', age: 24 }, { username: 'bob', age: 30 }]
console.log(users)
stringify(input, options)
它将一系列元素序列化为字符串. 如果参数为数组,输出为字符串. 整个转换在瞬间和记忆中进行. 如果论证是某种可重复的(同步或sync),输出会是同一种可输入可重复的.
input<Array> | <Iterable> | <AsyncIterable>options<Object>见 选项一节。 。 。 .- 回返情况:
<String> | <Iterable> | <AsyncIterable>
import { stringify } from '@evologi/fixed-width'
const users = [
{ username: 'alice', age: 24 },
{ username: 'bob', age: 30 }
]
const text = stringify(users, {
eof: true,
eol: '\n',
fields: [
{
align: 'left',
property: 'username',
width: 12
},
{
align: 'right',
pad: '0',
property: 'age',
width: 3
}
]
})
// 'alice 024\nbob 030\n'
console.log(text)
Parser.stream(options)
它返回一个 Transform stream ,以接受字符串(或缓冲)作为输入并释放解析出元素.
options<Object>见 选项一节。 。 。 .- 回返情况:
<Transform>
import { Parser } from '@evologi/fixed-width'
const stream = Parser.stream({
eol: '\n',
fields: [
{
property: 'username',
width: 12
},
{
cast: value => parseInt(value, 10),
property: 'age',
width: 3
}
]
})
stream
.on('error', err => console.error(err))
.on('data', data => console.log(data))
.on('end', () => console.log('end'))
stream.write('alice 024\nbob 030')
stream.end()
Stringifier.stream(options)
它返回一个 Transform stream 用于接受对象(o 数组)作为输入并释放串行.
options<Object>见 选项一节。 。 。 .- 回返情况:
<Transform>
import { Stringifier } from '@evologi/fixed-width'
const stream = Stringifier.stream({
eof: true,
eol: '\n',
fields: [
{
align: 'left',
property: 'username',
width: 12
},
{
align: 'right',
pad: '0',
property: 'age',
width: 3
}
]
})
let text = ''
stream
.on('error', err => console.error(err))
.on('data', data => { text += data.toString() })
.on('end', () => {
// 'alice 024\nbob 030\n'
console.log(text)
})
stream.write({ username: 'alice', age: 24 })
stream.write({ username: 'bob', age: 30 })
stream.end()
new Parser(options)
它创造了一个 Parser 举个例子 当需要自定义优化程序时,此对象是有用的 。 此对象被节点.js流和 parse() 函数.
options<Object>见 选项一节。 。 。 .- 回返情况:
<Parser>
它仅由两种方法组成,所有这些方法都是严格同步的.
Parser#write(stringOrBuffer)
它接受一个字符串或缓冲器作为输入,并返回一个可以输出所有解析对象到最后一行(行)的活性.
stringOrBuffer<String> | <Buffer>- 回返情况:
<Iterable>
Parser#end()
它重装 Parser 状态并返回可输出最后一个部分行(行)所包含其他对象的可操作性.
- 回返情况:
<Iterable>
import { Parser } from '@evologi/fixed-width'
const parser = new Parser({
eol: '\n',
fields: [
{
property: 'username',
width: 12
},
{
cast: value => parseInt(value, 10),
property: 'age',
width: 3
}
]
})
const users = Array.from(
parser.write('alice 024\nbob 030')
).concat(
Array.from(
parser.end()
)
)
// [{ username: 'alice', age: 24 }, { username: 'bob', age: 30 }]
console.log(users)
new Stringifier(options)
它创造了一个 Stringifier 举个例子 当需要自定义优化程序时,此对象是有用的 。 此对象被节点.js流和 stringify() 函数.
options<Object>见 选项一节。 。 。 .- 回返情况:
<Stringifier>
它仅由两种方法组成,所有这些方法都是严格同步的.
Stringifier#write(obj)
按一个对象来序列化 。 返回通过对象的序列文本,包括新的行终止符.
obj<*>- 回返情况:
<String>
Stringifier#end()
关闭解析并返回最后字符串.
- 回返情况:
<String>
import { Stringifier } from '@evologi/fixed-width'
const stringifier = new Stringifier({
eof: true,
eol: '\n',
fields: [
{
align: 'left',
property: 'username',
width: 12
},
{
align: 'right',
pad: '0',
property: 'age',
width: 3
}
]
})
let text = ''
text += stringifier.write({ username: 'alice', age: 24 })
text += stringifier.write({ username: 'bob', age: 30 })
text += stringifier.end()
// 'alice 024\nbob 030\n'
console.log(text)
选项
encoding
类型 : <String>
默认 : "uft8"
用于处理字符串和缓冲的编码. 仅 节点.js 编码 被支持.
eol
类型 : <String>
这个 页:1无 欧f 时 L内中区分记录行的字符.
它会打倒 os.EOL 用于序列化.
对于解析 Parser 将尝试猜测正确的行分隔符.
eof
类型 : <Boolean>
默认 : true
附加 页:1无 欧f 时 法语单色Char. 若为 true,一个 结束行 在文件末尾添加字符.
pad
类型 : string
默认 : " "
短于其字段宽度的值会在序列化时被添加到此值中. 也是解析时删除的修剪值.
见 trim, (中文(简体) ), field.pad,以及 field.align 选项.
trim
类型 : <Boolean> | <String>
默认 : true
它在解析时启用或禁用值的修剪 。 可能的值是:
true: 从两侧( 左右) 调整值false: 禁用修饰"left": 三进制值为左侧"right": Trim 值为右侧"auto":通过看田地来猜测修剪边align选项 :- 若为
field.align: "right"然后修剪左边 - 若为
field.align: "left"然后右调
- 若为
修剪值对应字段 嵌入值。 。 。 .
trim('004200', { pad: '0', trim: 'right' })
// the trimmed value will be '0042'
from
类型 : <Number>
默认 : 1
第一行在解析时考虑(包含).
这是一个 1个 整数( e)1 为第一行).
to
类型 : <Number>
默认 : Infinity
在解析时要考虑的最后一行( 包含) .
这是一个 1个 整数( e)1 为第一行).
allowLongerLines
类型 : <Boolean>
在解析时允许行长于声明的字段 .
默认 : true
allowShorterLines
类型 : <Boolean>
在解析时允许行比所声明的字段更短.
默认 : false
skipEmptyLines
类型 : <Boolean>
完全忽略所有空行 。 此选项确实 没有 改变 allowShorterLines 选项.
默认 : true
fields
类型 : <Array>
此选项是唯一需要的选项 。 它包含了所有字段的规格.
field.align
类型 : <String>
默认 : "left"
场值对接. 可能会 "left" 或者说 "right"。 。 。 .
field.cast
类型 : <Function>
一个接受原始字符串值并返回已解析的函数。 它还提供了上下文对象作为第二个参数. 只在解析时使用 .
const options = {
fields: [
{
width: 5,
cast: (value, ctx) => {
// value is always a string
// ctx = { column: 1, line: 1, width: 5 }
return parseInt(value)
}
}
]
}
field.column
类型 : <Number>
战地纵队. 这是 1个 值(一个是第一列)。 它默认为以前定义的所有字段宽度的总和.
field.pad
类型 : <Number>
字段级补丁值 。 它默认到 全球 一个.
field.property
类型 : <String> | <Symbol>
此选项控制输入对象和输出对象的预期格式.
分析
通过定义此选项 Parser 将发出对象。 如果该选项被省略,所释放的值将是数组.
序列化
通过定义此选项 Stringifier 将会需要对象。 如果省去该选项,预期值将是数组.
field.width
类型 : <Number>
田地宽. 要求.
field.stringify
类型 : <Function>
将字段转换成自定义字符串的函数。 用于自定义格式,例如将日期格式化为DD/MM/YYYY格式。 只在字符串时使用 .
field.trim
类型 : <Boolean> | <String>
默认: 回落到全局 trim 选项值.
外地一级 trim 选项.
见 trim 选项 医生.
错误
所有在解析或序列化相中可能发生的错误都包含一个出错代码. 出错对象还包含足够的信息(属性)来调试问题.
可以用其构造器检测自定义的固定宽误差:
import { FixedWidthError } from '@evologi/fixed-width'
try {
// parse or stringify...
} catch (err) {
if (err instanceof FixedWidthError) {
console.log(err.code)
} else {
console.log('UNKNOWN_ERROR')
}
}
UNEXPECTED_LINE_LENGTH
当找到部分行时, 此错误会上升 .
您可以用 allowLongerLines 或者说 allowShorterLines 选项.
EXPECTED_STRING_VALUE
当一个值不能被串行化为字符串时,这个错误会被提出来.
FIELD_VALUE_OVERFLOW
当一个字符串值的宽度超过其字段的宽度时,这个错误会上升.