javascript解析avro格式数据的探讨

标签: Avro 分类: Javascript 创建时间:2019-10-11 09:40:15 更新时间:2025-01-17 10:39:23

这篇文章其实说不上来有什么意义,其实就是记录自己如何解决浏览器端解析avro(大数据)格式的过程,最后能不能解决呢?还得看造化了。作为一个小前端,我只有瑟瑟发抖的份,撸起袖子加油干啊。

1.了解avro格式数据

2.查找到nodejs读取avro格式数据的方法

avsc-js说明:可以在浏览器中执行,但是仅仅实现了部分功能。在说明中有这么几句话:

(1) he same as here https://github.com/mtth/avsc#limitations.
(2) No support for file-related operations,so avsc.decodeFile  and avsc.getFileHeader are not available.      
(3) avsc.parse support schema as an object only (we cannot read file in browser so passing string will not work).

也就是说,avsc-js也不能进行解析avsc,当然,我通过ajax也尝试了将avro格式数据下载下来,然后用avsc解析,结果没有成功。

根据线索,我觉得既然是二进制数据,能不能自己解析呢?浏览器可以通过ArrayBuffer等数据类型进行二进制数据的解析。首先要知道avro数据格式的压缩代码的存储方式,只有知道了如何存储和压缩,才能知道如何读取。

参考文章:
1.Avro-js (avro的nodejs版实现,编写代码验证成功了)
2.Pure JavaScript implementation of the Avro specification:[avsc] (另一种nodejs实现)
3.Simple JavaScript wrapper for avsc module:[avsc-js] (和上面一样,不过多加了浏览器执行)
4.在javascript中使用Apache Avro (就是使用了avsc)
5.avro-rest-js (client-side and server-side javascript REST API example that receive and send AVRO buffer in request/response)
6.Avro的三种序列化方法
7.Apache Avro使用入门指南
8.Avro简介

还有一些其他的序列化和反序列化的介绍,基本上都是以管网的user例子开始和结束的。

3.尝试用二进制形式读取avro

大数据的二进制传输中间件:

一个存储文件由两部分组成:头信息(Header)和数据块(Data Block)。而头信息又由三部分构成:四个字节的前缀(类似于Magic Number),文件Meta-data信息和随机生成的16字节同步标记符。文档中指出当前Avro认定的就两个Meta-data:schema和codec。codec表示对后面的文件数据块(File Data Block)采用何种压缩方式。Avro的实现都需要支持下面两种压缩方式:null(不压缩)和deflate(使用Deflate算法压缩数据块)。除了文档中认定的两种Meta-data,用户还可以自定义适用于自己的Meta-data。这里用long型来表示有多少个Meta-data数据对,也是让用户在实际应用中可以定义足够的Meta-data信息。对于每对Meta-data信息,都有一个string型的key(需要以“avro.”为前缀)和二进制编码后的value。对于文件中头信息之后的每个数据块,有这样的结构:一个long值记录当前块有多少个对象,一个long值用于记录当前块经过压缩后的字节数,真正的序列化对象和16字节长度的同步标记符。由于对象可以组织成不同的块,使用时就可以不经过反序列化而对某个数据块进行操作。还可以由数据块数,对象数和同步标记符来定位损坏的块以确保数据完整性。
参考文章:
1.Buffer对象 (nodejs实现的二进制数据读取)
2.javascript处理二进制之ArrayBuffer
3.ArrayBuffer

4.ajax中从后台直接获取二进制数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var xhr = new XMLHttpRequest();
xhr.open('GET', './avro/users.avro', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
if (this.status == 200) {
// get binary data as a response
var blob = this.response;
console.log(blob);
var view=new Uint8Array(blob);
console.log(view);
console.log(String.fromCharCode(view[0]));
console.log(String.fromCharCode(view[1]));
console.log(String.fromCharCode(view[2]));
console.log(String.fromCharCode(22));

var pbf = new Pbf(new Uint8Array(this.response));
console.log(pbf);
// var str = pbf.readVarint();
// str = pbf.readVarint();
// str = pbf.readVarint();
// str = pbf.readVarint();

console.log(pbf.readString());
}
};

xhr.send();

输出结果:

参考文章:
1.[javascript读写二进制:javascript读写二进制
2.使用jQuery AJAX读取二进制数据:[使用jQuery AJAX读取二进制数据] (构造XMLHttpRequest,设置responseType为blob或者是
arraybuffer)

5.java用二进制流的方式读取avro格式数据

由于弄不清楚文件的二进制结构,所以我尝试在java端读取avro的二进制文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 //读取二进制数据
try {
DataInputStream dis = new DataInputStream(
new BufferedInputStream(new FileInputStream(
"D:\\zlc\\AvroJava\\users.avro")));
//System.out.println(Byte.parseByte(is.readUTF()));
int count = dis.available();

// create buffer
byte[] bs = new byte[count];

// read data into buffer
dis.read(bs);

// for each byte in the buffer
for (byte b:bs)
{
// convert byte into character
char c = (char)b;

// print the character
System.out.print(c+" ");
}


// System.out.println(is.readInt());
// System.out.println(is.readByte());
// System.out.println(is.readBoolean());
// System.out.println(is.readFloat());
// System.out.println(is.readLong());
// System.out.println(is.readUTF());

dis.close();
} catch (IOException e) {
System.out.println("dddd");
System.out.println(e);
}

结果读出来:

6.回顾avro数据结构

Avro支持的编程语言包括:C/C++,JAVA,Python,Ruby,PHP,C#,它的特点有:

丰富的数据结构类型
快速可压缩的二进制数据形式(对数据二进制序列化后可节约数据存储空间和网络传输带宽)
存储持久数据的文件容器
可实现远程过程调用(RPC)
简单的动态语言结合功能

7.使用nodepad++查看avro的二进制格式

(1) 打开nodepad++,菜单,选择安装插件,安装Hex-Editor插件。

(2) 打开avro文件,然后选择nodepad++菜单->插件->HEX-Editor->View in HEX,就可以查看文件的16进制形式了。

小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。