C#:COMP-3压缩十进制转换为人类可读的价值转换为、可读、人类、价值

2023-09-03 02:48:51 作者:Evildoer(妖孽)

我有一系列的ASCII纯文本文件从大型机进来由一个C#应用程序进行处理。一个新的进料已被引入用盒装十进制(COMP-3)域,需要被转换为数字值而

该文件正在通过FTP传输,使用ASCII传输模式。我担心的二进制字段可能包含的内容会PTED非常低的ASCII codeS或控制字符,而不是一间价值$ P $ - 或者更糟的是,可能会丢失在FTP进程

更重要的是,该领域正在被读为字符串。我可能要解决这部分(即某种流)的灵活性,但业务会给我推回。

要求改为从十六进制ASCII码转换,但显然这并不会产生正确的价值观。任何帮助将是AP preciated;它不需要特定语言的,只要你能解释一下转换过程的逻辑。

解决方案

首先,你必须消除的,将被ASCII传输模式造成行(EOL)翻译问题结束。你是绝对正确的进行数据损坏的担心,当BCD值正好对应于EOL字符。这个问题的最糟糕的方面是,它会很少发生和出乎意料

最好的解决办法是改变传输模式为BIN。这是恰当的,因为要传输的数据是二进制的。如果不能使用正确的FTP传输模式,可以撤消ASCII模式损害code。所有你需要做的就是转换\ r \ n对回为\ n。如果我是你,我会确保这是很好的测试。

一旦你已经处理了EOL问题,COMP-3的转换是pretty的straigtforward。我能找到在MS知识库样品code在基本这篇文章。请参阅下面的这个code一个VB.NET端口。

既然你要处理的COMP-3的值,你正在阅读几乎可以肯定的文件格式已经固定的记录大小固定字段长度。如果我是你,我会得到我的手的文件格式规范之前,您对此有何走得更远。应该使用一个BinaryReader在与此数据。如果有人推回在这一点上,我会走开。让他们找别人放纵自己的愚蠢。

下面是基本样本code一个VB.NET端口。我没有测试过这一点,因为我没有访问COMP-3文件。如果这也不行,我想请回原来的MS样品code指导,或者在其他的答案对这个问题的参考。

 进口Microsoft.VisualBasic程序

模块模块1

样品COMP-3的转换code
从http://support.microsoft.com/kb/65323改编
这code尚未经过测试

副主()

    昏暗位数%(15)举行了为每个号码(最多= 16)位。
    昏暗Basiceqv#(1000)举行的各COMP-3号基本相当。

    加入使code编译
    昏暗MyByte为CHAR,豪鹏%,HighNibble%
    朦胧LowNibble%,位%,E%,十进制%,文件名$


    清屏,得到的文件名和小数量
    希望每个数字,并打开顺序输入的文件:
    文件名$ =输入框(输入COBOL数据文件名:)
    十进制%=输入框(输入小数位数所希望的:)

    的FileOpen(1,文件名$,OpenMode.Binary)

    做直到EOF(1)'循环直到该文件的结尾为止。
        输入(1,MyByte)
        如果MyByte = CHR(0),那么'检查字节为0(ASC将无法在0工作)。
            位数%(豪鹏%)= 0'让接下来的两个数字0增量
            数字%(豪鹏%+ 1)= 0'的高功率,以反映
            豪鹏%=豪鹏%+ 2'编号中的号码的数字
            加1。
        其他
            HighNibble%=升序(MyByte)\ 16中提取的高和低
            LowNibble%=升序(MyByte)和放大器; HF'从字节半字节。该
            位数%(豪鹏%)= HighNibble%'高四位永远是
            '数字。
            如果LowNibble%< = 9然后'如果低四位是
                数字,它分配和
                位数%(%豪鹏+ 1)= LowNibble%'增量高
                豪鹏%=%豪鹏+ 2权力相应。
            其他
                豪鹏%=%豪鹏+ 1低四位是不是数字而是
                位%= 0'+或 - 号的信号端。

                开始以10的最高功率的数量和乘
                每一个数字的10处占用的权力。
                对于功率%=(%豪鹏 -  1)0步骤-1
                    Basiceqv#(E%)= Basiceqv#(E%)+(数字%(位%)*(10 ^功率%))
                    位%=位%+ 1
                下一个

                如果符号读为负,使得一些负面的。
                如果LowNibble%= 13然后
                    Basiceqv#(E%)= Basiceqv#(E%) - (2 * Basiceqv#(E%))
                结束如果

                给的小数位数所需要的量,打印
                '的数量,增量E&以指向下一个数为
                转换,并重新初始化最高权力。
                Basiceqv#(E%)= Basiceqv#(E%)/(10 ^十进制%)
                打印(Basiceqv#(E%))
                Ë%= E%+ 1
                豪鹏%= 0
            结束如果
        结束如果
    循环

    FILECLOSE()'关闭COBOL数据文件,并结束。
结束小组

前端模块
 

干货 如何同时压缩多个PDF文件

I have a series of ASCII flat files coming in from a mainframe to be processed by a C# application. A new feed has been introduced with a Packed Decimal (COMP-3) field, which needs to be converted to a numerical value.

The files are being transferred via FTP, using ASCII transfer mode. I am concerned that the binary field may contain what will be interpreted as very-low ASCII codes or control characters instead of a value - Or worse, may be lost in the FTP process.

What's more, the fields are being read as strings. I may have the flexibility to work around this part (i.e. a stream of some sort), but the business will give me pushback.

The requirement read "Convert from HEX to ASCII", but clearly that didn't yield the correct values. Any help would be appreciated; it need not be language-specific as long as you can explain the logic of the conversion process.

解决方案

First of all you must eliminate the end of line (EOL) translation problems that will be caused by ASCII transfer mode. You are absolutely right to be concerned about data corruption when the BCD values happen to correspond to EOL characters. The worst aspect of this problem is that it will occur rarely and unexpectedly.

The best solution is to change the transfer mode to BIN. This is appropriate since the data you are transferring is binary. If it is not possible to use the correct FTP transfer mode, you can undo the ASCII mode damage in code. All you have to do is convert \r\n pairs back to \n. If I were you I would make sure this is well tested.

Once you've dealt with the EOL problem, the COMP-3 conversion is pretty straigtforward. I was able to find this article in the MS knowledgebase with sample code in BASIC. See below for a VB.NET port of this code.

Since you're dealing with COMP-3 values, the file format you're reading almost surely has fixed record sizes with fixed field lengths. If I were you, I would get my hands of a file format specification before you go any further with this. You should be using a BinaryReader to work with this data. If someone is pushing back on this point, I would walk away. Let them find someone else to indulge their folly.

Here's a VB.NET port of the BASIC sample code. I haven't tested this because I don't have access to a COMP-3 file. If this doesn't work, I would refer back to the original MS sample code for guidance, or to references in the other answers to this question.

Imports Microsoft.VisualBasic

Module Module1

'Sample COMP-3 conversion code
'Adapted from http://support.microsoft.com/kb/65323
'This code has not been tested

Sub Main()

    Dim Digits%(15)       'Holds the digits for each number (max = 16).
    Dim Basiceqv#(1000)   'Holds the Basic equivalent of each COMP-3 number.

    'Added to make code compile
    Dim MyByte As Char, HighPower%, HighNibble%
    Dim LowNibble%, Digit%, E%, Decimal%, FileName$


    'Clear the screen, get the filename and the amount of decimal places
    'desired for each number, and open the file for sequential input:
    FileName$ = InputBox("Enter the COBOL data file name: ")
    Decimal% = InputBox("Enter the number of decimal places desired: ")

    FileOpen(1, FileName$, OpenMode.Binary)

    Do Until EOF(1)   'Loop until the end of the file is reached.
        Input(1, MyByte)
        If MyByte = Chr(0) Then     'Check if byte is 0 (ASC won't work on 0).
            Digits%(HighPower%) = 0       'Make next two digits 0. Increment
            Digits%(HighPower% + 1) = 0   'the high power to reflect the
            HighPower% = HighPower% + 2   'number of digits in the number
            'plus 1.
        Else
            HighNibble% = Asc(MyByte) \ 16      'Extract the high and low
            LowNibble% = Asc(MyByte) And &HF    'nibbles from the byte. The
            Digits%(HighPower%) = HighNibble%  'high nibble will always be a
            'digit.
            If LowNibble% <= 9 Then                   'If low nibble is a
                'digit, assign it and
                Digits%(HighPower% + 1) = LowNibble%   'increment the high
                HighPower% = HighPower% + 2            'power accordingly.
            Else
                HighPower% = HighPower% + 1 'Low nibble was not a digit but a
                Digit% = 0                  '+ or - signals end of number.

                'Start at the highest power of 10 for the number and multiply
                'each digit by the power of 10 place it occupies.
                For Power% = (HighPower% - 1) To 0 Step -1
                    Basiceqv#(E%) = Basiceqv#(E%) + (Digits%(Digit%) * (10 ^ Power%))
                    Digit% = Digit% + 1
                Next

                'If the sign read was negative, make the number negative.
                If LowNibble% = 13 Then
                    Basiceqv#(E%) = Basiceqv#(E%) - (2 * Basiceqv#(E%))
                End If

                'Give the number the desired amount of decimal places, print
                'the number, increment E% to point to the next number to be
                'converted, and reinitialize the highest power.
                Basiceqv#(E%) = Basiceqv#(E%) / (10 ^ Decimal%)
                Print(Basiceqv#(E%))
                E% = E% + 1
                HighPower% = 0
            End If
        End If
    Loop

    FileClose()   'Close the COBOL data file, and end.
End Sub

End Module