我目前正在编写一个c#应用程序,它将位于两个现有应用程序之间。我所知道的第二个应用程序是它处理第一个应用程序生成的文件。第一个申请是用Cobol编写的。
步骤: 1)Cobol应用程序,将一些文件和副本写入目录。 2)第二个应用程序选择这些文件并处理它们。
我的C#应用程序将介于1)和2)之间。它必须拿起1)生成的文件,读取它,修改它并保存它,以便应用程序2) 我不知道自己到过那里。
我有一些问题。
我曾尝试以这种方式阅读文件,但它仍然无法读取:
代码:
string ss = @"filename";
using (FileStream fs = new FileStream(ss, FileMode.Open))
{
StreamReader sr = new StreamReader(fs);
string gg = sr.ReadToEnd();
}
此外,如果我找到一种方法使其可读(使用某种编码技术),我担心当我再次保存文件时,我可能会改变它的原始格式。
有什么想法?建议?
答案 0 :(得分:27)
要阅读COBOL-genned文件,您需要知道:
首先,您需要文件的记录布局(字帖)。 COBOL记录布局如下所示:
01 PATIENT-TREATMENTS.
05 PATIENT-NAME PIC X(30).
05 PATIENT-SS-NUMBER PIC 9(9).
05 NUMBER-OF-TREATMENTS PIC 99 COMP-3.
05 TREATMENT-HISTORY OCCURS 0 TO 50 TIMES
DEPENDING ON NUMBER-OF-TREATMENTS
INDEXED BY TREATMENT-POINTER.
10 TREATMENT-DATE.
15 TREATMENT-DAY PIC 99.
15 TREATMENT-MONTH PIC 99.
15 TREATMENT-YEAR PIC 9(4).
10 TREATING-PHYSICIAN PIC X(30).
10 TREATMENT-CODE PIC 99.
您还需要IBM的操作原理(S / 360,S370,z / OS,对我们的目的并不重要)的副本。最新消息来自IBM
第8章(十进制指令)和第9章(浮点概述和支持指令)是我们的目的。
没有它,你几乎迷失了。
然后,您需要了解COBOL数据类型。例如:
如果数据源是IBM大型机,则COMP-1和COMP-2可能不会是IEE浮点:它将是IBM的base-16 excess 64 floating point format。你需要像 S / 370操作原理这样的东西来帮助你理解它。
PIC S9999V99 COMP-3
。这表示它是有符号的,由6位十进制数字组成,带有隐含的小数点。压缩十进制表示每个十进制数字作为八位位组的半字节(十六进制值0-9)。高位数是最左边八位位组的高位半字节。最右边的八位字节的低半字节是表示符号的十六进制值A-F。所以上面的PIC
子句需要ceil( (6+1)/2 )
或4个八位字节。上面的PIC
子句所表示的值-345.67看起来像0x0034567D
。实际符号值可能不同(默认值为C /正,D /负,但A,C,E和F被视为正数,而只有B和D被视为负数)。同样,请参阅 S \ 370操作原理以获取有关表示的详细信息。与COMP-3相关的是十进制分区。这可能被声明为“PIC S9999V99”(带符号,5位十进制数字,带有隐含的小数点)。 EBCDIC中的十进制数字是十六进制值0xFO - 0xF9。 '解包'(主机机器指令)采用压缩十进制字段并转入字符字段。这个过程是:
从右到左(源和目标两者)工作,剥离压缩十进制字段的每个剩余半字节,并将其放入目标中下一个可用八位字节的低半字节。用十六进制F填充高半字节。
当源字段或目标字段用尽时,操作结束。
如果目标字段没有用完,如果用零填充剩余的八位字节为“0”(oxF0),则用零填充。
因此,我们的示例值-345.67,如果以默认符号值(十六进制D)存储,将被解压缩为0xF0F0F0F3F4F5F6D7('0003456P',在EBDIC中)。
[你走了。稍后会有一个小测验]
哦......最后一件事。大型机硬件往往喜欢在半字,字或双字边界上对齐的不同内容,因此记录布局可能不会直接映射到文件中的八位字节,因为字段之间可能会插入填充八位字节以维持所需的字对齐。
祝你好运。
答案 1 :(得分:2)
知道你正在处理哪个Cobol Dialect是有用的,因为有 没有单一的Cobol格式。一些Cobol编译器(Micro Focus)在文件前面放置了一个“文件描述”(用于Micro Focus VB /索引文件)。
查看RecordEditor(http://record-editor.sourceforge.net/)。它有一个文件向导,对您来说非常有用。
除非文件来自Mainframe / AS400,否则不太可能使用EBCDIC(cp037 - Coded Page 37是US EBCDIC),任何文本最有可能出现在Ascii中。
该文件可能包含Packed-Decimal(Comp3)和Binary-Integer数据。大多数Cobols 即使在英特尔(小端硬件)上也使用Big-Endian(用于Comp整数)。
Cobol PIC s9(6)V99 comp要记住的一件事是存储为二进制整数,x'0001'代表0.01。因此,除非你有Cobol定义,否则你不能告诉二进制1是1 0.1,0.01等
答案 2 :(得分:2)
我从您的问题附带的评论中看到,您正在处理“经典”COBOL批处理文件结构:标题记录,详细记录和预告片记录。
如果您负责创建预告片记录,这可能是个坏消息!典型的“预告片”记录用于识别文件结尾并提供控制信息,例如其前面的记录数量以及“详细”记录的各种校验和和/或总计。换句话说,您可能需要阅读并汇总整个文件才能创建预告片。除此之外,文件中的大部分数据都是Packed Decimal,Zoned Decimal或其他COBOLish数字数据类型的可能性,您可能会遇到困难。
您可能想要质疑为何将拖车记录添加到这些文件中。通常,“预告片”由创建“详细”记录的相同程序或应用程序生成。预告片应该作为验证发送应用程序/程序写下它应该的所有数据。接收应用程序使用摘要总计,计数等来验证详细记录与前面的详细信息一致。这应该作为另一个验证,发送应用程序没有消除数据或它没有在途中损坏(不,这不是一个笑话 - 但也许应该是)。当一个“中间人”创造了预告片时,它会破坏练习的整个目的(无论它开始时有多么瑕疵)。