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

用FileIO读取二进制数据

排行榜 收藏 打印 发给朋友 举报 来源: 译自director-online.com   发布者:David Pollock
热度173票  浏览759次 时间:2007年1月25日 17:20
  原著:David Pollock 奥古多媒体4Ay!VZ%SKtqm
  翻译:DCM奥古多媒体'ASJg"_2j

-d$i~%sY0   我有一个project,需要直接从以二进制形式储存的数据库中读取数据。看来我需要诸如BinaryIO或者BinaryMaster的Xtra去从磁盘上读取了,但是利用FileIO,做稍许工作,也可以做到读写二进制文件。奥古多媒体&~$P["egS*j;z-oC
奥古多媒体n+C"L x;b6d
  FileIO专注于一件事情:读写ASCII文本文件。不能读取二进制文件的主要原因是当遇到0字节时,被当作ASCII字符0-即空字符-文件结束的标志。因为二进制文件中有大量的0存在,你也就不能读出所需要的数据了。
)@4JJK;c9cL0
8VQ#v/dU ie j7T"A0   FileIO中的getLength和readChar函数
8Go;R6{JRc(L`:I+n0
;G2L!W.Rx)_m0   幸运的是,FileIO有许多其它的函数让我们绕过这个限制。首先是Getlength,能够准确地得到文件的字节数(在文本文件中,一个字节代表一个ASCII字节,但在二进制中不同,在后面再来解释)。
@{7YM4u zo k:U[#^0   其次我们会以ReadChar代替ReadFile。ReadChar读取一个字节或字符后,移到下一个字节并等待。重要的是ReadChar并不关心读到字节是否是0,它将返回一个空字符串给Lingo交移到下一个字节。奥古多媒体zp@8i?9eA#s M],Ez

|sDfe,Y0   二进制数据奥古多媒体4mi)Vu0j2h8m ^V
奥古多媒体~.S*V3KKN)T
  现在我们有办法知道文件中有多少字节,也能够读取每一个字节了。接下来的事情是什么数据是我们所需要的。如果我们保存所有读取到的字节,问题不亚于用ReadFile函数了。在Lingo中,0字节等同于empty,或者" ",在字符串中不会增加任何东西。
pmvz$VQOk0 奥古多媒体c|qm$f
  很明显的变通办法是将所有读出的数据作为一个字符串保存在线性列表里(也有其它办法,例如使用Image object),再由CharToNum函数将这些字符串数据转换成数字。这样,文件中每个字节的值都可加入线性列表中,我们就可以操作这些数据了。下面是其代码:
{KP%sZ~IM[X0 奥古多媒体,JoTt,GEjYGo%H
on readBinaryFile filePath
-@0@J(v2u5T0 -- Call handler using the full file path
3sC6T5vOiU&T%F0
'wjHTS!o0 byteList = []奥古多媒体FI_2lh)`6U
-- This list will contain all of the byte values retrieved奥古多媒体+{(@J4@/Kw zY"L
fileObj = new(xtra "fileIO")奥古多媒体BFM:o'ySy-}
fileObj.openFile(filePath, 1)奥古多媒体5fYKQv-RHD
-- Open the file with read-only access 奥古多媒体e2N/s)C|3Ev3~ J9N1fe
奥古多媒体3v4J bT&M S#t-A2K
if fileObj.status() = 0 then
w7`A@Gg*h ^q0 fileLength = fileObj.getLength()奥古多媒体nkyi+I*M@v
-- Find the length of the file in bytes
yq/n8s'LG0 repeat with index = 1 to fileLength奥古多媒体/EG2K] O
byteList.append(charToNum(fileObj.readChar()))奥古多媒体_Z9|8Q(^~\
-- Append the value of each byte of the file to byteList奥古多媒体 dC Dq){Xu.]^ T
end repeat奥古多媒体J%mag#d4W.I3M B
end if
:j$]'onI0
V`@!n6q0 fileObj.closeFile()
cu'bo k#gK Kb C8v `0 -- Close the file奥古多媒体QH){7|ny$j fS
fileObj = 0
@)l5CpHp0 -- Clear the FileIO instance from memory奥古多媒体;`:Mp4e5U H
return byteList奥古多媒体*f n&fu#rN

|%w8bt;p H9FO0 end 奥古多媒体ph?N%{

jG9f'}|4_O0   关键在于弄清Repeat循环,结合使用ReadChar函数,让FileIO保持从文件中读取数据,不管所遇到的字符值。这样我们就有办法完整地读取任何文件。奥古多媒体U"j0O*V9F C.m
奥古多媒体l-}%{V0J%A^1Qx
  读取长文件 奥古多媒体'c&R]hYK:] {\:G3D

h.R/NEI1u r0   你会想到的一个问题是,使用readBinaryFile程序读取长文件时会返回一个极大的byteList 变量,占用许多内存。假如我们知道哪部分数据是我们想要的,可以这样作轻微的修改。奥古多媒体$A)j A#e'LOt

1|X:y,atI0 on readBinaryFile filePath, startByte, endByte
q#@#Hq6fD0 -- Optional parameters for specifying positions in the file奥古多媒体l*A H7Q!bXCW1}
byteList = []奥古多媒体5WoiYH.U9u@f
fileObj = new(xtra "fileIO")
L(MN'L/Fu)X-X7X:Tw!X0 fileObj.openFile(filePath, 1)
*K&tu0V u+Q5p7P-n r0
j:a2` XBM3G0 if fileObj.status() = 0 then
0X{_G8l,C0 fileLength = fileObj.getLength()
I:YYC{[4kh0
e1v4a*]6kS#~I)i+ho0 if startByte.voidP then奥古多媒体 bn`;N bM{0g&h
-- Read entire file if parameters aren't supplied奥古多媒体M4YG T)CR!x,l ybc
startByte = 1
7z6p%Y8Rr*_4T/i,?0 endByte = fileLength
yR7r#g5NU0 end if奥古多媒体,C.RYHP*u~K7U
奥古多媒体 V}3i1E%ikF7^"^4x
奥古多媒体fcX K+v xo
if (fileLength >= startByte) and (fileLength >= endByte) then
:T&a/x U)C$L ~mL0 fileObj.setPosition(startByte-1)奥古多媒体jTM;N3uI^"QN
-- Position FileIO to read from the correct point in the file奥古多媒体-QM%dg1u4c0M
repeat with index = startByte to endByte
6?;S { [~ ^G'wBE0 byteList.append(charToNum(fileObj.readChar()))
/T0N dtZIgIL0 end repeat
Y},P8\Mv%P0 end if奥古多媒体Kg!S~(j$s;y!dE8s"l
end if
h:lt*c4]{4}0
h~`#qx!O9pl5S0 fileObj.closeFile()
~0s4RTN_b0 fileObj = 0奥古多媒体 a8rl-J9p5\'n3|p'g
return byteList
[7NA+MoB0 end 奥古多媒体y @8? O+c
奥古多媒体 en*N'n D S;s
  例子:读取MP3标签
ca'?'e0YB j)B-i0
7fY'nZp{c4s;DH3\6H0   使用这个程序的真实例子是读取MP3文件标签。MP3文件标签存储在最后的128个字节中。本例子包含有一个Director movie,说明是如何做到这一点的(需要FileXtra和FileIO Xtra)。关于文件格式,可参考www.wotsit.org奥古多媒体F~E'J_f+A:OJ
奥古多媒体iw!P!d(lm:U1}
  此例子程序从MP3文件中读取了诸如歌名、歌手、专辑名、年份、风格等信息。奥古多媒体E'e!~uj#R8CZ5D

wl,x\+_0 on readMP3tags filePath奥古多媒体0ccnN,F8]{4a1^!d
奥古多媒体4ANn G`
fileLength = getFileSizeInBytes (filePath)奥古多媒体2X l7BY X YJ
if fileLength > 0 then奥古多媒体GE+U5tHY9[
byteList = readBinaryFile (filePath, fileLength - 127, fileLength)奥古多媒体UR}/f?2v\$a
tagStr = ""奥古多媒体p+\%c4_1S2g{?
repeat with index = 1 to byteList.count奥古多媒体)~9Mlo0`6bd H
tagStr = tagStr & numToChar (byteList[index])
O)kFCs2A/~P)~i0 end repeat
u2tS!y|0 奥古多媒体Q9];fj7|P-I*[^
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)]
Jf2w K"A'f'p0
/fh)l-|i0Qtj4h0 repeat with index = 1 to tags.count
ZFBh@J0 memberName = string (tags.getPropAt (index))奥古多媒体 D8dl-P"C${+n
newText = clipString (tags[index])
8X9Gx$zn Y0 member (memberName).text = newText
TC S3yo$Js.L0 end repeat奥古多媒体B2nE%X2THbs `
end if奥古多媒体IlT]|'s(CPovF

u"o@*l#Z/vS\0 end
I4^4j6fo1|,@m2G0
$U.CM!X3Z&}(N0 相关附件
顶:8 踩:11
对本文中的事件或人物打分:
当前平均分:0.04 (54次打分)
对本篇资讯内容的质量打分:
当前平均分:0.57 (49次打分)
【已经有51人表态】
10票
感动
6票
路过
6票
高兴
6票
难过
5票
搞笑
5票
愤怒
5票
无聊
8票
同情
上一篇 下一篇

网络资源


音乐
嫁衣 画心 歌曲 天亮了 青花瓷 那滋味 Nobody 没有如果 不了了之 爱的华尔兹 生生世世爱 i miss you 说好的幸福呢 如果我变成回忆 在心里从此永远有个你
火苗 心碎 稻香 带我走 我知道 爱得起 我叫mt 类似爱情 明天过后 一定要爱你 等爱的玫瑰 原谅我一次 丢了幸福的猪 斯琴高丽的伤心 这一生回忆有你就足够
白狐 偏爱 犯错 下雨天 小酒窝 樱花草 此生不换 分身情人 郎的诱惑 姑娘我爱你 寂寞才说爱 关不上的窗 一个人的浪漫 即使知道要见面 不是因为寂寞才想你
拾忆 王妃 心墙 全是爱 棉花糖 最天使 少女时代 爱丫爱丫 星空物语 我要的飞翔 我们都一样 我叫小沈阳 爱我就跟我走 让我为你唱首歌 爱上你等于爱上了错