- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一系列来自大型机的 ASCII 平面文件,由 C# 应用程序处理。引入了带有压缩十进制 (COMP-3) 字段的新提要,需要将其转换为数值。
文件正在通过 FTP 传输,使用 ASCII 传输模式。我担心二进制字段可能包含将被解释为非常低的 ASCII 代码或控制字符而不是值的内容 - 或者更糟的是,可能会在 FTP 过程中丢失。
此外,字段被读取为字符串。我可能可以灵活地解决这部分问题(即某种流),但公司会给我回击。
要求是“Convert from HEX to ASCII”,但显然没有产生正确的值。任何帮助,将不胜感激;只要您能解释转换过程的逻辑,它就不必特定于语言。
最佳答案
我一直在关注许多关于将 Comp-3 BCD 数据从“遗留”大型机文件转换为可在 C# 中使用的文件的帖子。首先,我想说的是,我对其中一些帖子收到的回复并不感兴趣——尤其是那些基本上说“你为什么要用这些非 C#/C++ 相关的帖子来打扰我们”以及“如果您需要有关某种 COBOL 约定的答案,为什么不去访问面向 COBOL 的站点”。对我来说,这是完全的废话,因为可能需要很多年(不幸的是)让软件开发人员了解如何处理现实世界中存在的一些遗留问题。因此,即使我在这篇文章中因为以下代码而受到猛烈抨击,我仍将与您分享我必须处理的关于 COMP-3/EBCDIC 转换的真实世界经验(是的,我就是谈论“软盘、纸带、光盘包等...-我从 1979 年开始就是一名软件工程师”)。
首先 - 了解您从 IBM 等遗留大型机系统读取的任何文件都将以 EBCDIC 格式向您呈现数据,并且为了将任何数据转换为您可以处理的 C#/C++ 字符串您将不得不使用正确的代码页转换将数据转换为 ASCII 格式。如何处理这个问题的一个很好的例子是:
StreamReader readFile = new StreamReader(path, Encoding.GetEncoding(037);//037 = EBCDIC 到 ASCII 的转换。
这将确保您从此流中读取的任何内容都将转换为 ASCII,并可以以字符串格式使用。这包括 COBOL 声明的“分区十进制”(图 9)和“文本”(图 X)字段。但是,当读入 char[] 或 byte[] 数组时,这并不一定会将 COMP-3 字段转换为正确的“二进制”等价物。要做到这一点,您将获得正确翻译(甚至使用 UTF-8、UTF-16、默认或其他)代码页的唯一方法,您将要像这样打开文件:
FileStream fileStream = new FileStream(path, FIleMode.Open, FIleAccess.Read, FileShare.Read);
当然,“FileShare.Read”选项是“可选的”。
当您分离出要转换为十进制值的字段(如果需要,随后转换为 ASCII 字符串),您可以使用以下代码 - 这基本上是从 MicroSoft“UnpackDecimal”中窃取的您可以在以下位置发布:
我已经分离(我认为)这个逻辑中最重要的部分是什么,并将其合并为两个方法,您可以随心所欲地进行操作。出于我的目的,我选择将其保留为返回一个 Decimal 值,然后我可以用我想要的来做。基本上,该方法称为“unpack”,您向它传递一个 byte[] 数组(不超过 12 个字节)和作为 int 的比例,这是您希望在 Decimal 值中返回的小数位数。我希望这对你和我一样有用。
private Decimal Unpack(byte[] inp, int scale)
{
long lo = 0;
long mid = 0;
long hi = 0;
bool isNegative;
// this nybble stores only the sign, not a digit.
// "C" hex is positive, "D" hex is negative, and "F" hex is unsigned.
switch (nibble(inp, 0))
{
case 0x0D:
isNegative = true;
break;
case 0x0F:
case 0x0C:
isNegative = false;
break;
default:
throw new Exception("Bad sign nibble");
}
long intermediate;
long carry;
long digit;
for (int j = inp.Length * 2 - 1; j > 0; j--)
{
// multiply by 10
intermediate = lo * 10;
lo = intermediate & 0xffffffff;
carry = intermediate >> 32;
intermediate = mid * 10 + carry;
mid = intermediate & 0xffffffff;
carry = intermediate >> 32;
intermediate = hi * 10 + carry;
hi = intermediate & 0xffffffff;
carry = intermediate >> 32;
// By limiting input length to 14, we ensure overflow will never occur
digit = nibble(inp, j);
if (digit > 9)
{
throw new Exception("Bad digit");
}
intermediate = lo + digit;
lo = intermediate & 0xffffffff;
carry = intermediate >> 32;
if (carry > 0)
{
intermediate = mid + carry;
mid = intermediate & 0xffffffff;
carry = intermediate >> 32;
if (carry > 0)
{
intermediate = hi + carry;
hi = intermediate & 0xffffffff;
carry = intermediate >> 32;
// carry should never be non-zero. Back up with validation
}
}
}
return new Decimal((int)lo, (int)mid, (int)hi, isNegative, (byte)scale);
}
private int nibble(byte[] inp, int nibbleNo)
{
int b = inp[inp.Length - 1 - nibbleNo / 2];
return (nibbleNo % 2 == 0) ? (b & 0x0000000F) : (b >> 4);
}
如果您有任何问题,请在此处发布 - 因为我怀疑我会像其他选择发布与当今问题相关的问题的其他人一样“发怒”...
谢谢,约翰 - 长者。
关于C#:将 COMP-3 压缩十进制转换为人类可读的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/142972/
我在不同的硬件上测试 Cassandra 已经有一段时间了。 首先我有 2 个 CPU 和 6 GB RAM 然后我更改为 16 个 CPU 和 16 GB RAM(其中只有 6 GB 可供我的测试使
我只是想从二进制文件中读/写。我一直在关注 this教程,它的工作原理......除了它似乎正在将内容写入 txt 文件。我在测试的时候把文件命名为test.bin,但是记事本可以打开并正常显示,所以
我编写了一些简单的 Java 代码来从文本文件中读取字符串,将它们组合起来,然后将它们写回。 (有关输出没有变化的简化版本,请参见下面的片段) 问题是输入文件和输出文件中的特定字符(- 和 ...)是
我真的很感兴趣——你为什么要放 readln; 从键盘读取一些值到变量后的行?例如, repeat writeln('Make your choise'); read(CH); if (CH = '1
只要程序不允许同时写入存储在模块中的共享数据结构的相同元素,它是线程安全的吗?我知道这是一个菜鸟问题,但在任何地方都找不到明确解决的问题。情况如下: 在程序开始时,数据被初始化并存储在模块级可分配数组
我有一个数据结构,其操作可以归类为读取操作(例如查找)和写入操作(例如插入、删除)。这些操作应该同步,以便: 读操作不能在写操作执行时执行(除非在同一线程上),但是读操作可以与其他读操作并发执行。 在
我在Java套接字编程中有几个问题。 在读取客户端套接字中的输入流时,如果抛出IO异常;那么我们是否需要重新连接服务器套接字/再次初始化客户端套接字? 如果我们关闭输出流,它将关闭客户端套接字吗? 如
我正在尝试从客户端将结构写入带有套接字的服务器。 结构是: typedef struct R { int a; int b; double c; double d; double result[4];
我想知道是否可以通过 Javascript 从/向 Azure Active Directory 广告读取/写入数据。我读到 Azure 上有 REST 服务,但主要问题是生成与之通信的 token
我希望有人能提供完整的工作代码,允许在 Haskell 中执行以下操作: Read a very large sequence (more than 1 billion elements) of 32
我有一个任务是制作考试模拟器。我的意思是,在老师输入某些科目的分数后,学生输入他的名字、姓氏和出生,然后他决定学生是否通过科目。所以,我有一个问题,如何用新行写入文件文本并通过重写该文件来读取(逐行读
我需要编写巨大的文件(超过 100 万行)并将文件发送到另一台机器,我需要使用 Java BufferedReader 一次读取一行。 我使用的是 indetned Json 格式,但结果不太方便,
我在 Android 应用程序中有一个读写操作。在 onCreate 上,将读取文件并将其显示为编辑文本并且可以进行编辑。当按下保存按钮时,数据将被写入 onCreate 上读取的同一文件中。但我得到
我正在编写一个程序,该程序从一个文件读取输入,然后该程序将格式化数据并将其写入另一个文件。 输入文件: Christopher kardaras,10 N Brainard,Naperville,IL
我有一个 SCALA(+ JAVA) 代码,它以一定的速率读写。分析可以告诉我代码中每个方法的执行时间。如何衡量我的程序是否达到了最大效率?为了使我的代码优化,以便它以给定配置可能的最大速度读取。我知
嗨,我想知道如何访问 java/maven 中项目文件夹中的文件,我考虑过使用 src/main/resources,但有人告诉我,写入此目录中的文件是一个坏主意,并且应该只在项目的配置中使用,所以我
我想读\写一个具有以下结构的二进制文件: 该文件由“RECORDS”组成。每个“RECORD”具有以下结构:我将以第一条记录为例 (红色)起始字节:0x5A(始终为 1 字节,固定值 0x5A) (绿
我想制作一个C程序,它将用一些参数来调用;每个参数将代表一个文件名,我想在每个参数中写一些东西。 FILE * h0; h0 = fopen(argv[0],"w"); char buff
我有一个包含团队详细信息的文件。我需要代码来读取文件,并将获胜百分比写入第二个文件。我还需要使用指示的搜索功能来搜索团队的具体信息。该代码未写入百分比文件。当菜单显示时,第一个文件的内容被打印,但代码
我正在使用 read() 和 write() 函数来处理我的类,并且我正在尝试使用一个函数来写入它所读取的内容以及我作为参数给出的前面的内容。 例如,我想给出 10 作为我的程序的参数 int mai
我是一名优秀的程序员,十分优秀!