clean文件的感悟
(2008-07-17 12:21:49)
标签:
it |
最近在用VB做一个clean possible_hifrm的小工具
一开始的做法,就是以unicode的格式读取文件内容到一个string,然后在string里匹配到<iframe>,然后删除,最后再回写
后来发现这样做之后,写回后的文件很多都无法打开
研究了一顿之后,发现是因为二进制编码的问题,以下摘自一个专家的答复:
在VB中一定要记住,不能使用String变量处理二进制数据。早期的VB是采用单字节处理方式(通常也称为ANSI方式),也就说一个英文字母用一个字节表示,一个汉字算两个字节,当然这样就可能出现半个汉字的问题。从VB 4.0起,VB采用了一种新的处理方式,即内部采用Unicode方式,即不论英文字母还是汉字,一律用两个字节表示,但Unicode还不够普及,所以VB只是在其内部完全使用Unicode,而在外部仍转换为人们习惯的ANSI方式,但在字符串处理上与先前的版本有所不同。例如:在中文Windows或英文Windows外挂RichWin 97中,Len("电子&电脑")=5(这里的&号为半角字符),而在以前的版本或纯英文Windows中Len("电子&电脑")=9。除了Len、Left、Right等字符串函数受此影响外,所有字符操作都受此影响。如果你把二进制数据读入字符串变量,在读入的过程中会发生转换错误,这样你再写入文件数据也就不对了。以上的讨论对于中文等双字节系统都是适用的,但英文版下没有这个问题。所以,你在网上看到的许多程序因为都是美国人写的,他们根本就不考虑这个问题,使用字符串来处理二进制数据,但这样的程序在中文系统中肯定出错。解决的办法是使用Byte数组来处理二进制数据,这样就不会有你说的问题了。例如:
Dim n As Long
Dim arrBytes() As Byte
Open "c:\win98\setup.bmp" For Binary As 1
n = LOF(1)
ReDim arrBytes(1 To n) As Byte
Get 1, , arrBytes
Close 1
If arrBytes(1) = Asc("B") And arrBytes(2) = Asc("M") Then
MsgBox "这是一个位图文件。"
End If
后来我按照这个思路继续做下去,但是发现如果一开始以二进制数组读文件,那匹配<iframe>就是一个问题。因为Byte数组里都是二进制文件,而且是不连续的,所以要搜索一个string肯定是有难度的。
我目前的做法是:
1·byte数组读文件
2·byte数组转成string:A
3·将要匹配的字符串转成byte数组,然后再转string:B
4·在A中以正则表达式搜索B
5·如果匹配到,则在A中找到B的位置:C
6·在byte数组中删除C位置的项,调整数组大小
7·回写文件
这样做有两个瓶颈:
1·VB本身对数组转换支持的不好,如果要将类似{12,23,34}的数组转成“122334”的string,只能循环遍历数组,这个效率很低,尤其是遇到大文件
2·在A中找到B的位置,并且反馈给数组,这个逻辑复杂,而且VB在这方面的效率也不高。
更好的方法,我目前还在寻找:)
作者:Jason Zhou
发布:2008-07-17