我使用JavaScript通过互联网获取数据(我正在与经纪公司的API函数进行接口),但是与大多数其他API不同的是,该API以“二进制”格式返回数据。这是我返回的文件的布局:
Field -------- Type ------------ Length(8 bit bytes) --------------- Description
Symbol Count----Integer------------- 4--------------------------- Number of symbols for which data is being returned. The subsequent sections are repeated this many times
REPEATING SYMBOL DATA
Symbol Length Short 2 Length of the Symbol field
Symbol String Variable The symbol for which the historical data is returned
Error Code Byte 1 0=OK, 1=ERROR
Error Length Short 2 Only returned if Error Code=1. Length of the Error string
Error Text String Variable Only returned if Error Code=1. The string describing the error
Bar Count Integer 4 # of chart bars; only if error code=0
REPEATING PRICE DATA
close Float 4
high Float 4
Low Float 4
open Float 4
volume Float 4 in 100's
timestamp Long 8 time in milliseconds from 00:00:00 UTC on January 1, 1970
END OF REPEATING PRICE DATA
Terminator Bytes 2 0xFF, 0XFF
END OF REPEATING SYMBOL DATA
如您所见,此文件是不同类型字段的混合。我的要求是将此文件从其方式转换为固定字段文本文件(或CSV文件)。我不太擅长JavaScript,但我足够了解。我的主要语言是Unisys的MAPPER(实际上称为“业务信息服务器”)。当前,我所有的HTTP响应都以文本文件形式获得,但是此文件是“二进制”文件,由于它是基于文本的语言(一种4GL),因此MAPPER无法处理它。我花了几天的时间试图找到我可以使用的JavaScript代码段,但无济于事。我认为对于一个懂JavaScript的人来说,这确实是一件简单的事情。
最佳答案
我是UNISYS程序员。在2200大型机上使用25年的FORTRAN 77。幸运的是,我很少与MAPPER有任何关系。
我想提供帮助,但您没有提供足够的信息。
此JavaScript代码在哪里运行?在浏览器中,或者它是对您用来访问MAPPER的任何东西的扩展?
您正在使用某种终端模拟器吗? AttachMate?
您的数据是真正到达文件中还是存储在内存中?您如何接收它,如何传递内容?
在JavaScript中进行处理是否至关重要?如果数据以文件形式存在并且输出也应该是文件,那么有数十种语言会使任务工作非常短。
我看到的一个问题是,AFAIK,JavaScript不了解文件IO。这就是为什么我要问它在哪里运行。
编辑:
好的,以某种方式,您有一个类似于浏览器的环境并在其中运行JavaScript。
首先,从响应中获取二进制数据的问题。这里有一些帮助:
https://developer.mozilla.org/en/using_xmlhttprequest
这是Mozilla文档,在“接收二进制数据”下,但是我希望会有足够的重叠部分,以使其有用:
function load_binary_resource(url) {
var req = new XMLHttpRequest();
req.open('GET', url, false);
//XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
return req.responseText;
}
上面的内容使您可以稍微摆弄连接以获得希望的二进制数据。
该函数的调用方式如下:
var filestream = load_binary_resource(url);
var abyte = filestream.charCodeAt(x) & 0xff;
...如果我正确理解的话,您的
responseText
是一个JavaScript字符串(照常),但是由于摆弄和二进制内容,它不包含可打印文本,而是包含二进制数据。呵呵,只要您不尝试解释它,就像任何旧文本一样,它只是一系列字节。第二行让您从字符串中的任何位置提取单个字节。该字节为0到255之间的值;如果您不走运,则介于-128到127之间。不确定JavaScript如何处理带符号字节。
这看起来对您不利。让我们看看如何获取数据:
您的数据以名为
short
的symbolLength
开始。我猜一个short
是2个字节,我猜charCodeAt()
的偏移量是从0开始的。因此,您需要的是前两个字节,即字节0和1。我不确定是否您的数据将采用高位或低位,但是您应该能够从任一var symbolLength = fileStream.charCodeAt(0) + 256 * fileStream.charCodeAt(1);
要么
var symbolLength = 256 * fileStream.charCodeAt(0) + fileStream.charCodeAt(1);
换句话说,使用乘法将字节重新组合为整数。
整数大概是4个字节,因此您将乘以4的256的幂:16777216、65536、256和1-再次以该顺序或相反的顺序。
当然,String数据就是这样,一旦考虑了前面字段占用的字节数,您就应该能够简单地使用子字符串运算符从响应字符串中挖掘出来。
现在是令人讨厌的部分-
short
s的转换。这些数字的内部结构由IEEE 754定义。 float
可能对应于float
,binary32
(如果有)对应于double
。我链接的Wikipedia文章中的链接很好地解释了这些格式,以至于如果您精疲力尽,您可以编写自己的转换例程,但是我会穿上鞋子寻找为此的现成代码。当然,您不是第一个将少数字节转换为浮点数的人。也许您可以找到一些可以手动转换的C或Java代码,或者甚至可以找到已经用JavaScript编写的例程。最后,一旦有了转换所有提到的数据类型的方法,您所需要做的就是将数据格式化为想要在MAPPER下游看到的任何格式。遍历结构,增加偏移量的指针……可能对您而言没有什么新意。
诚然,我在这里做了很多猜测和挥手。这可能是解决方案的开始,但您可能需要做一些试验,并提出一些详细问题。不要提及UNISYS,请说出您的问题,好像您想在IE中这样做:)
第一步,我尝试将传入的二进制字符串以字节为单位(最好以十六进制)转储到某种介质中,您可以在其中读取它,并将看到的字节与输入数据中期望的字节进行比较。
关于javascript - 从“二进制格式”文件中提取值并创建具有固定字段大小的文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3374479/