JS幻想 读取二进制文件第1/2页

 更新时间:2009年04月20日 15:25:34   作者:   我要评论
如果说让JavaScript读取站点上一文本文件,那不过是个再简单不了的事了;但若说要换成一个二进制的文件,并且是完全静态的读取,那似乎有点天方夜谭了。
且不说浏览器内置的HTTP插件是否支持二进制数据流,就JavaScript其自身就毫无二进制的处理能力。聪明的读者也许想说用VBScript就可以实现了。不错,因为VBScript,IE,ActiveX都是微软的产物,所以他们有着无缝的结合。IE的HTTP组件确实能够读取二进制数据,而且也只能够让VBScript读取。但对于其他浏览器,就束手无策了。

毕竟脚本的理念仅仅是用来处理一些简单的交互的,对于处理字节流之类的复杂问题完全不该是脚本的职责。不过作为一种探索,我们还是可以挖掘下其中的乐趣。当然,首先要明确的是,对于二进制的读取JS确实是无能为力的,不过我们可以来模拟,以达到相同的效果,下面就跟着我来吧。

比如现在想要做个推箱子的小游戏,共200关。这时唯一值得考虑到事就出现了:把这200关地图数据保存在何处?如果直接硬塞在一个脚本文件里似乎显得太大,或者单独保存在一个文件里,但是用什么格式。。。不过对于推箱子游戏来说简单的文本格式也够了,但对于一些地图较复杂的也许就会使用BASE64编码,然后由客户端的HTTP组件下载下来解码使用。BASE64编码在JS中还是很常用的,毕竟它不受任何的环境限制,能够处理字符串就行。

既然有个BASE64,那为什么就不能有BASE128,BASE256了呢?如果能实现“BASE256”,岂不就是二进制字节流了?如果真可以如此,那这种方法早就流传开了,还留着那么多的BASE64做什么:)毕竟这是字符串,而不叫字节串,那肯定是有区别的。不妨把一个二进制的文件,当作文本文件读取回来试试,很快你就会发现超过一旦文件中出现127(0x7F)以上的字符,马上就出错了;如果存在个0x00字节的话,后面的内容都会荡然无存,这意味着256个字符中能够利用的还不到一半。

然而,可别忘了这个测试使用的仅仅是最基本的ASCII编码,对于功能强大的XMLHTTP支持的也绝不仅限于如此,那么就试试Unicode字符会怎样。在记事本随便输几个字符,保存为Unicode格式的文本文件。这时用XMLHTTP读取,显示出来的与记事本里的一模一样,但是再用16进制编辑器打开此文件时,就大不相同了。在文件的开头出现了FF FE两字节,后面的每个内容都是由一个0隔开。毕竟这是16位的Unicode字符,除了基本的ASCII外,还要保存各国的文字。例如一个中文就占用了2个字节,而英文数字仍然占用2字节,只是高位由0填充罢了(注意高位字节是在低位字节后面的)。
XMLHTTP能够成功显示出来就说明Unicode还是支持的。现在试着修改文件里面的数据,看看超过了那些范围才会出错。把数据修改成如下:FFFE 0001 0203 7F00 8000 8100 FF00 FFFF。用XMLHTTP测试,虽然显示的都是乱码,但并没出错,返回的字符串用charCodeAt(i)及toString(16)方法一试,原形毕露!几经测试,Unicode并不像ASCII那样有范围限制,但唯独一个例外:0x0000!
众所周知,0x00就是ASCII的结束标志。但到了Unicode的世界里一切都是16位的,因此字符尾也成了0x0000。到了这里似乎有点遗憾,但接着的目标很明确:如果能够去掉文件中的0x0000,并在之前加上0xFEFF,就能够让JavaScript读取了。

去掉以及恢复,不妨就称他编码与解码吧。编码的方法就见智见仁了,最简单的办法就是记录下每个0x0000的位置,然后除去;在客户端按照记录的位置再复原回去。虽然简单,但也别忘了,0x00在二进制文件中是相当多的,即便是0x0000也是。这样光是记录他们的内容就有很多,显然不是很好。既然说到要记录,为何一定要记录0x0000的位置?反过来想,我们应该记录这个文件中出现次数最少的字符,以及它的位置,然后把0x0000的地方替换成这个字符;解码的时候一旦出现这个字符,但当前位置又不在记录中,就可以确定这就是个0x0000。事实上,在64K以下的文件中肯定有个字符根本就不会出现的(为什么仔细考虑下就明白),即使是在64K以上,还是有非常多的文件不存在某个字符的。毕竟一个Unicode字符有65536之多,很少有文件会把他们全都用上,除非是个冗余极小的压缩文件,但也不会很多。

到此,编码解码思路已明了,剩下自然是实现他们。
刚才提到了源文件中出现最少(甚至是没有)的Unicode字符,不妨就称作key
首先来定义新生成的二进制文件头格式:
复制代码 代码如下:

00 01 0xFEFF。 Unicode文件头,这是必须的
02 03 Key值。 为了不让0x0000成为Key,在寻找的过程中忽略0x0000
03 04 Key出现的次数+1。 +1是为了避免该位置出现0x0000,后面的也都一样
05 06
07 08 第1个Key的位置 用4字节保存每个Key的位置。
09 0A
0B 0C 。。。
0D 0E
0F 10 第n个Key的位置
11 12 文件数据内容。。。

相关文章

  • 可选择和输入的下拉列表框示例

    可选择和输入的下拉列表框示例

    如果想实现可选择和输入的下拉列表框,那么下面有个不错的示例,希望大家可以参考下
    2013-11-11
  • JS拉起或下载app的实现代码

    JS拉起或下载app的实现代码

    最近做项目遇到这样的需求,通过手机网页判断是否安装了自己公司app,如果安装了则拉起app,没有安装则跳转到下载页。怎么实现呢?下面小编给大家分享js拉起或下载app的实现代码,需要的朋友参考下
    2017-02-02
  • JavaScript 程序错误Cannot use ''in'' operator to search的解决方法

    JavaScript 程序错误Cannot use ''in'' operator to search的解决

    下面小编就为大家带来一篇JavaScript 程序错误Cannot use 'in' operator to search的解决方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • js getBoundingClientRect() 来获取页面元素的位置

    js getBoundingClientRect() 来获取页面元素的位置

    该方法已经不再是IE Only了,FF3.0+和Opera9.5+已经支持了该方法,可以说在获得页面元素位置上效率能有很大的提高,在以前版本的Opera和Firefox中必须通过循环来获得元素在页面中的绝对位置。
    2010-11-11
  • 详解JavaScript逻辑And运算符

    详解JavaScript逻辑And运算符

    这篇文章主要介绍了JavaScript逻辑And运算符,在JavaScript中,逻辑 AND 运算符用双和号(&&)表示
    2015-12-12
  • Layui 导航默认展开和菜单栏选中高亮设置的方法

    Layui 导航默认展开和菜单栏选中高亮设置的方法

    今天小编就为大家分享一篇Layui 导航默认展开和菜单栏选中高亮设置的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 使用javascript做时间倒数读秒功能的实例

    使用javascript做时间倒数读秒功能的实例

    今天小编就为大家分享一篇关于使用javascript做时间倒数读秒功能的实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • js HTML5 Ajax实现文件上传进度条功能

    js HTML5 Ajax实现文件上传进度条功能

    这篇文章主要介绍了javascript实现文件上传进度条功能的相关资料啊,感兴趣的朋友可以参考一下
    2016-02-02
  • Select2.js下拉框使用小结

    Select2.js下拉框使用小结

    这篇文章主要为大家详细总结了Select2.js下拉框的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • JavaScript知识点整理

    JavaScript知识点整理

    本文是脚本之家小编日常整理的关于javascript知识点,包括javascript拥有的特点,组成部分,数据类型等方面,对javascript知识点相关知识感兴趣的朋友一起学习吧
    2015-12-12

最新评论