• 2006-07-17

    当Ruby遇到二进制

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/2854532.html

    最近在用C写一些处理图像的程序。如果你尝试一下你就会知道调试这种程序会是怎样的痛苦,它的复杂在于大数据量。比如一个简单的八邻域处理,就需要该点周围八个象素的值。在C的开发环境下,查看变量是一种恶梦,我需要一个一个把所有变量敲进去,而其差异仅仅是地址上的差1。这时候倒是有点怀念Matlab了,至少在那里面,按照矩阵处理的图像,可以很容易的查看。于是决定写一个小工具,帮自己一把。

    主意拿定之后,就是选择语言了。因为Ruby一天比一天火,于是我准备尝试用Ruby去写这个工具。Ruby对我来说,跟Web没什么太大关系,我只是用它去帮助自己完成一些日常工作而已。去年的时候,Python扮演过这个角色。用惯了Java和C这种“重量级”语言,尝试一下这种动态语言,感觉还是颇为不错的,写出来的代码很简洁。之前一天用Ruby写了一个小程序,对Ruby有了一个初步的认识,基本上一边翻文档一边写程序就可以把程序写出来,有时候凭感觉写的代码居然也是对的,这可能就是Matz所说的最小惊奇吧!于是满怀希望的准备用Ruby写自己的小工具。

    结果是……,我还是用C写了这个工具。为什么?这就是我要写这篇blog的目的。

    对于处理文本文件来说,Ruby一点问题都没有,甚至可以把程序写得很优雅(甚至诡异)。但我处理的目标是图像,换句话说,是一种二进制文件。这时候,语言的缺陷就暴露出来了。

    Ruby也可以读二进制文件(IO类的read),但我们知道通常处理的二进制文件都是有一定格式的。在C语言中,我们会定义一个struct,然后一个fread就可以把内容读到变量中,代码像这样:
    fread(record, sizeof(record), 1, file);

    在Ruby中怎么做呢?我能找到的方法只是读一个字段,写一个字段。所以,如果写出来,代码会比较冗长,这是让我望而却步的主要原因。而且在读写字段的时候,还要注意字段的大小。虽然用Ruby写的大多数代码要比C简单得多,但是,面对二进制时,Ruby却显得如此笨拙。

    这应该不是Ruby中独有的问题,同样的问题我也在Java中发现过。记得BCEL在处理class文件的时候,就是这么一个一个字段的处理。

    与其说,这是语法上的缺陷,不如说,这是为了GC付出的代价。之所以在C语言中那得天独厚的表达方式源自对内存的控制,面对二进制的时候,我们只要简单的内存对拷。不过在这个层面上,我们忽略了逻辑含义。使用Ruby、Python和Java这些支持GC的语言时,我们做不到,因为我们无法触及内存,它们抛弃了恼人的内存烦恼,也扔掉使用内存的优点。这就是平衡的结果吧!

    在Ruby方面,我是新手,对于某些问题的理解可能不够准确,如果你对上面的叙述有异议,或有好的做法,请指教。

    分享到:

    历史上的今天:

    引用地址:

    评论

  • #!/usr/bin/env ruby



    File.open('in.dat', 'rb') {|fin|

    File.open('out.dat', 'wb') {|fout|

    fout.print(fin.read)

    }

    }



    说话要负责任,不用会别误导人
  • 关注你的blog已经好久了,喜欢读dreamhead你写的文字,感觉就像和一位师兄在聊天、谈心,很容易产生共鸣。明天回家了,开学后继续关注,呵呵。