在 Apache Beam 中将 EBCDIC 转换为 ASCII
Convert EBCDIC to ASCII in Apache Beam
我正在尝试使用来自 Apache Beam 中 JRecord 的 CobolIoProvider class 将 EBCDIC 文件转换为 ASCII。
我正在使用的代码:
CobolIoProvider ioProvider = CobolIoProvider.getInstance();
AbstractLineReader reader = ioProvider.getLineReader(Constants.IO_FIXED_LENGTH, Convert.FMT_MAINFRAME,CopybookLoader.SPLIT_NONE, copybookname, cobolfilename);
代码根据需要读取并转换文件。我只能从本地系统读取 cobolfilename 和 copybookname,它们基本上分别是 EBCDIC 文件和 copybook 的路径。但是,当我尝试从 GCS 读取文件时,它失败并显示 FileNotFoundException – “文件名、目录名或卷标语法不正确”。
有没有办法使用 CobolIoProvider class 从 GCS 读取 Cobol 文件 (EBCDIC)?
如果没有,是否有任何其他 class 可用于将 Cobol 文件 (EBCDIC) 转换为 ASCII 并允许从 GCS 读取文件。
使用 ICobolIOBuilder:-
我使用的代码:
ICobolIOBuilder iob = JRecordInterface1.COBOL.newIOBuilder("copybook.cbl")
.setFileOrganization(Constants.IO_FIXED_LENGTH)
.setSplitCopybook(CopybookLoader.SPLIT_NONE);
AbstractLineReader reader = iob.newReader(bs); //bs is an InputStream object of my Cobol file
但是,这里有一些问题:-
1) 我必须将 copybook.cbl 保存在本地。有什么方法可以从 GCS 读取副本文件。我尝试了以下代码,试图将我的抄写本从 GCS 读取到 Stream 并将流传递给 LoadCopyBook()。但是代码没有用。
示例代码如下:
InputStream bs2 = new ByteArrayInputStream(copybookfile.toString().getBytes());
LayoutDetail schema = new CobolCopybookLoader()
.loadCopyBook( bs, " copybook.cbl",
CopybookLoader.SPLIT_NONE, 0, "",
Constants.USE_STANDARD_COLUMNS,
Convert.FMT_INTEL, 0, new TextLog())
.asLayoutDetail();
AbstractLineReader reader = LineIOProvider.getInstance().getLineReader(schema);
reader.open(inputStream, schema);
2) 使用 newReader 从流中读取 EBCDIC 文件没有将我的文件转换为 ascii。
谢谢。
将 Beam/Dataflow 用于新型基于文件的来源的最简单方法是首先使用 FileIO
获得 PCollection<ReadableFile>
然后使用 DoFn
阅读那个文件。这将需要实现代码以从给定通道读取。类似于以下内容:
Pipeline p = ...
p.apply(FileIO.match().filepattern("..."))
.apply(FileIO.readMatches(...))
.apply(new DoFn<ReadableFile, String>() {
@ProcessElement
public void processElement(ProcessContext c) {
try (ReadableByteChannel channel = c.element().open()) {
// Use CobolIO to read from the byte channel
}
});
我没有完整的答案。如果您使用的是最新版本,建议更改 JRecord 代码以使用 JRecordInterface1。 IO-Builder 比旧的 CobolIoProvider 接口灵活得多。
String encoding = "cp037"; // cp037/IBM037 US ebcdic; cp273 - German ebcdic
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder("CopybookFile.cbl")
.setFileOrganization(Constants.IO_FIXED_LENGTH)
.setFont(encoding); // should set encoding if you can
AbstractLineReader reader = iob.newReader(datastream);
通过 IO-Builder 接口,您可以使用流。这个问题 是关于从 GCS 创建流的,可能会有用。希望对 GCS 有更多了解的人可以提供帮助。
或者,您可以直接从 GCS 读取并使用 JRecord-IO-Builder[=] 的 newLine 方法创建数据行(数据记录) 28=]:
AbstractLine l = iob.newLine(byteArray);
我将着眼于为 JRecord 创建一个基本的 Read/Write 接口,以便 JRecord 用户可以编写自己的 GCS 或 IBM 大型机访问 (ZFile) 等接口。但这需要时间。
我正在尝试使用来自 Apache Beam 中 JRecord 的 CobolIoProvider class 将 EBCDIC 文件转换为 ASCII。
我正在使用的代码:
CobolIoProvider ioProvider = CobolIoProvider.getInstance();
AbstractLineReader reader = ioProvider.getLineReader(Constants.IO_FIXED_LENGTH, Convert.FMT_MAINFRAME,CopybookLoader.SPLIT_NONE, copybookname, cobolfilename);
代码根据需要读取并转换文件。我只能从本地系统读取 cobolfilename 和 copybookname,它们基本上分别是 EBCDIC 文件和 copybook 的路径。但是,当我尝试从 GCS 读取文件时,它失败并显示 FileNotFoundException – “文件名、目录名或卷标语法不正确”。
有没有办法使用 CobolIoProvider class 从 GCS 读取 Cobol 文件 (EBCDIC)?
如果没有,是否有任何其他 class 可用于将 Cobol 文件 (EBCDIC) 转换为 ASCII 并允许从 GCS 读取文件。
使用 ICobolIOBuilder:-
我使用的代码:
ICobolIOBuilder iob = JRecordInterface1.COBOL.newIOBuilder("copybook.cbl")
.setFileOrganization(Constants.IO_FIXED_LENGTH)
.setSplitCopybook(CopybookLoader.SPLIT_NONE);
AbstractLineReader reader = iob.newReader(bs); //bs is an InputStream object of my Cobol file
但是,这里有一些问题:-
1) 我必须将 copybook.cbl 保存在本地。有什么方法可以从 GCS 读取副本文件。我尝试了以下代码,试图将我的抄写本从 GCS 读取到 Stream 并将流传递给 LoadCopyBook()。但是代码没有用。
示例代码如下:
InputStream bs2 = new ByteArrayInputStream(copybookfile.toString().getBytes());
LayoutDetail schema = new CobolCopybookLoader()
.loadCopyBook( bs, " copybook.cbl",
CopybookLoader.SPLIT_NONE, 0, "",
Constants.USE_STANDARD_COLUMNS,
Convert.FMT_INTEL, 0, new TextLog())
.asLayoutDetail();
AbstractLineReader reader = LineIOProvider.getInstance().getLineReader(schema);
reader.open(inputStream, schema);
2) 使用 newReader 从流中读取 EBCDIC 文件没有将我的文件转换为 ascii。
谢谢。
将 Beam/Dataflow 用于新型基于文件的来源的最简单方法是首先使用 FileIO
获得 PCollection<ReadableFile>
然后使用 DoFn
阅读那个文件。这将需要实现代码以从给定通道读取。类似于以下内容:
Pipeline p = ...
p.apply(FileIO.match().filepattern("..."))
.apply(FileIO.readMatches(...))
.apply(new DoFn<ReadableFile, String>() {
@ProcessElement
public void processElement(ProcessContext c) {
try (ReadableByteChannel channel = c.element().open()) {
// Use CobolIO to read from the byte channel
}
});
我没有完整的答案。如果您使用的是最新版本,建议更改 JRecord 代码以使用 JRecordInterface1。 IO-Builder 比旧的 CobolIoProvider 接口灵活得多。
String encoding = "cp037"; // cp037/IBM037 US ebcdic; cp273 - German ebcdic
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder("CopybookFile.cbl")
.setFileOrganization(Constants.IO_FIXED_LENGTH)
.setFont(encoding); // should set encoding if you can
AbstractLineReader reader = iob.newReader(datastream);
通过 IO-Builder 接口,您可以使用流。这个问题
或者,您可以直接从 GCS 读取并使用 JRecord-IO-Builder[=] 的 newLine 方法创建数据行(数据记录) 28=]:
AbstractLine l = iob.newLine(byteArray);
我将着眼于为 JRecord 创建一个基本的 Read/Write 接口,以便 JRecord 用户可以编写自己的 GCS 或 IBM 大型机访问 (ZFile) 等接口。但这需要时间。