你的位置:奥古多媒体 >> 资讯 >> 教程 >> Director教程 >> 详细内容 在线投稿

用FileIO读取二进制数据

排行榜 收藏 打印 发给朋友 举报 来源: 译自director-online.com   发布者:David Pollock
热度376票  浏览794次 时间:2007年1月25日 17:20
  原著:David Pollock
7i3{+Py*t W/nc0   翻译:DCM
L$G \] c w2T#F)S0 奥古多媒体JD i:Q4j%O,O,d@;w
  我有一个project,需要直接从以二进制形式储存的数据库中读取数据。看来我需要诸如BinaryIO或者BinaryMaster的Xtra去从磁盘上读取了,但是利用FileIO,做稍许工作,也可以做到读写二进制文件。
^Iy1D7b.^'g0
Sc%K0u(v7^7_MC:[x@0   FileIO专注于一件事情:读写ASCII文本文件。不能读取二进制文件的主要原因是当遇到0字节时,被当作ASCII字符0-即空字符-文件结束的标志。因为二进制文件中有大量的0存在,你也就不能读出所需要的数据了。
I^lx[t;~0 奥古多媒体&K1Q!lm;O,aO
  FileIO中的getLength和readChar函数奥古多媒体ZUM!P_#~ t-Mm

r ^F#q"^0   幸运的是,FileIO有许多其它的函数让我们绕过这个限制。首先是Getlength,能够准确地得到文件的字节数(在文本文件中,一个字节代表一个ASCII字节,但在二进制中不同,在后面再来解释)。奥古多媒体%X%w Mv+e+lL2C
  其次我们会以ReadChar代替ReadFile。ReadChar读取一个字节或字符后,移到下一个字节并等待。重要的是ReadChar并不关心读到字节是否是0,它将返回一个空字符串给Lingo交移到下一个字节。
)Zn(A|Tk OZ0
4SG2mzm6p0   二进制数据
;u d D svi%P+]0
4vh`-P;D~7R.{XGn0   现在我们有办法知道文件中有多少字节,也能够读取每一个字节了。接下来的事情是什么数据是我们所需要的。如果我们保存所有读取到的字节,问题不亚于用ReadFile函数了。在Lingo中,0字节等同于empty,或者" ",在字符串中不会增加任何东西。
#j$}[y8J*W&dc`d0
"vAos:Wq(Q6TEN0   很明显的变通办法是将所有读出的数据作为一个字符串保存在线性列表里(也有其它办法,例如使用Image object),再由CharToNum函数将这些字符串数据转换成数字。这样,文件中每个字节的值都可加入线性列表中,我们就可以操作这些数据了。下面是其代码:奥古多媒体wO9s9tv
奥古多媒体-~,jsAY cd.`5n
on readBinaryFile filePath
.Z9s0GAB"z&L'H0 -- Call handler using the full file path
c Z,\R} q)w&p.H0
!\(f:P bG @C1HR0 byteList = []奥古多媒体PA w Y b"EF.K:~
-- This list will contain all of the byte values retrieved奥古多媒体5?-QgU;_zp2`
fileObj = new(xtra "fileIO")奥古多媒体 h u(n3u[
fileObj.openFile(filePath, 1)
K~xM^Q0 -- Open the file with read-only access
;M u[T#` }!e1n0 奥古多媒体8L i)wh F/d3x
if fileObj.status() = 0 then
:k[cC(z/w&tN0 fileLength = fileObj.getLength()奥古多媒体2|K9On YS_
-- Find the length of the file in bytes
qc-~.IQ8I i1J-F0 repeat with index = 1 to fileLength奥古多媒体/b7QJxwE+Mn8j
byteList.append(charToNum(fileObj.readChar()))
Q&FV/V0a4Q0 -- Append the value of each byte of the file to byteList奥古多媒体:_ U1gv)jt_g/O
end repeat奥古多媒体$D;k }7Q;r{ @
end if 奥古多媒体1b1m1dU|u;ag
奥古多媒体.p7S;dZ!U\
fileObj.closeFile()奥古多媒体`0b8}b_ef
-- Close the file
H@8?j7FK0~ L5W6W0 fileObj = 0
8k,Pr^6Qz&u4_ q0 -- Clear the FileIO instance from memory奥古多媒体$B!Btb{N:a&Y
return byteList奥古多媒体4d#p;IVY/V

o;Rd'k6w9Z0 end 奥古多媒体 D{9kj1F:Z7M1R |0~
奥古多媒体 d0w8QD&{5gm5xS
  关键在于弄清Repeat循环,结合使用ReadChar函数,让FileIO保持从文件中读取数据,不管所遇到的字符值。这样我们就有办法完整地读取任何文件。
"R0Z6ifEF0
~mOy\L[Q H:c.Md0   读取长文件
Ob-wu$wt0
0QL"h4j?*nU#_3Y~0   你会想到的一个问题是,使用readBinaryFile程序读取长文件时会返回一个极大的byteList 变量,占用许多内存。假如我们知道哪部分数据是我们想要的,可以这样作轻微的修改。
[ grz$yM0 奥古多媒体zk(pRE[
on readBinaryFile filePath, startByte, endByte
8P^@%c/m8V]0 -- Optional parameters for specifying positions in the file
D%O5?,Qj#A \N0 byteList = []
6\GW? G(c0 fileObj = new(xtra "fileIO")奥古多媒体Ml`3Y| S2Lk$Rs
fileObj.openFile(filePath, 1)
q E*p LJ y U:gs0
6D?2V1w MXa9?&d0 if fileObj.status() = 0 then
L;e^S{o0 fileLength = fileObj.getLength()奥古多媒体b4{*\\Kg |,yE
奥古多媒体h?l}a-J e&Y,n
if startByte.voidP then
QI-d/Z7O+O)`|m0 -- Read entire file if parameters aren't supplied
@,d9i9UxSa5M0 startByte = 1奥古多媒体K;A+d+}hM)e
endByte = fileLength奥古多媒体-g^(sW1R-s:hf&H q
end if奥古多媒体+P UX!B%`o2q

*xkQ!h bqnj0
fPdSyi0 if (fileLength >= startByte) and (fileLength >= endByte) then
2f Ze0Q4Xk[0 fileObj.setPosition(startByte-1)
thidVB/^;?0 -- Position FileIO to read from the correct point in the file
+e:I,Zma$vXN0 repeat with index = startByte to endByte
![Y eWoWS0 byteList.append(charToNum(fileObj.readChar()))
q3K8x[0HR0 end repeat奥古多媒体*E |"]Hxeqq$Q
end if奥古多媒体+e|5p[$t
end if
O|7eH&V+l!I8ileo(@%g0
L(A&b\f0 fileObj.closeFile()
{C[+|3YmPd0 fileObj = 0奥古多媒体`K\!V @0I
return byteList
j0uD+wNPmH0 end
E!I4vgTH Y0 奥古多媒体/H"rt/f.ihq7m
  例子:读取MP3标签
|^)H U-E3VEQ0 奥古多媒体,^OUZJR ]!?
  使用这个程序的真实例子是读取MP3文件标签。MP3文件标签存储在最后的128个字节中。本例子包含有一个Director movie,说明是如何做到这一点的(需要FileXtra和FileIO Xtra)。关于文件格式,可参考www.wotsit.org奥古多媒体@+Z,u!DsNh

0WJ}kGk mh(c9[0   此例子程序从MP3文件中读取了诸如歌名、歌手、专辑名、年份、风格等信息。奥古多媒体_&x-|4k,n"@ `"Q

:UZ3y2Os9BQ,C ow0 on readMP3tags filePath
#[&OB#@ jlI"R0 奥古多媒体*H*BSf s TBuC|)u
fileLength = getFileSizeInBytes (filePath)奥古多媒体e/l;u M;r%{
if fileLength > 0 then
wEg5Z+SrT0 byteList = readBinaryFile (filePath, fileLength - 127, fileLength)
#ZT8Ugw5M |/mqX0 tagStr = ""
v@H)Z9c(X8S](~mY+K0 repeat with index = 1 to byteList.count
qDw${ v x)[%C0 tagStr = tagStr & numToChar (byteList[index])奥古多媒体1})ci;n uiw!TeK#Z H]w
end repeat奥古多媒体4P*n_j!c@
奥古多媒体L UcTjMKS
tags = [#title: tagStr.char[4..33], #artist: tagStr.char[34..63], #album: tagStr.char[64..93], #year: tagStr.char[94..97], #genre: getGenre (charToNum (tagStr.char[128]) + 1)]
9i6o"ay&m8URB0 奥古多媒体 n S3jKe%`
repeat with index = 1 to tags.count
!O/r EY4L]0 memberName = string (tags.getPropAt (index))奥古多媒体kq.S)nN3?H Q m
newText = clipString (tags[index])奥古多媒体9Z-\R:j,i,F
member (memberName).text = newText
&|"x;m$XR@m d0 end repeat
4Gv2XaI4`)e8Y0 end if
%_|5q/J{(X!H0
$S!N:x'}gM lE0 end
GId4R#i,ND4Y&@&x0
@3v'L u+U}0 相关附件
顶:23 踩:18
对本文中的事件或人物打分:
当前平均分:0 (117次打分)
对本篇资讯内容的质量打分:
当前平均分:0.16 (106次打分)
【已经有112人表态】
19票
感动
14票
路过
16票
高兴
17票
难过
11票
搞笑
11票
愤怒
10票
无聊
14票
同情
上一篇 下一篇

网络资源