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

用FileIO读取二进制数据

排行榜 收藏 打印 发给朋友 举报 来源: 译自director-online.com   发布者:David Pollock
热度184票  浏览761次 时间:2007年1月25日 17:20
  原著:David Pollock 奥古多媒体K(X;KWB3V
  翻译:DCM奥古多媒体 nm,EM Z`

5yQE(l2tFN.?0   我有一个project,需要直接从以二进制形式储存的数据库中读取数据。看来我需要诸如BinaryIO或者BinaryMaster的Xtra去从磁盘上读取了,但是利用FileIO,做稍许工作,也可以做到读写二进制文件。奥古多媒体Y(XD4w~ ZBuh#z

2]bUB2D/E0W$d4e0   FileIO专注于一件事情:读写ASCII文本文件。不能读取二进制文件的主要原因是当遇到0字节时,被当作ASCII字符0-即空字符-文件结束的标志。因为二进制文件中有大量的0存在,你也就不能读出所需要的数据了。
(gY-tE5v5mmgI0 奥古多媒体 {V/SD O0bD-q_
  FileIO中的getLength和readChar函数奥古多媒体 j.d/p,G\$[L
奥古多媒体 m!Et)E#OU~7l
  幸运的是,FileIO有许多其它的函数让我们绕过这个限制。首先是Getlength,能够准确地得到文件的字节数(在文本文件中,一个字节代表一个ASCII字节,但在二进制中不同,在后面再来解释)。
$_v#Ns;FH9P0   其次我们会以ReadChar代替ReadFile。ReadChar读取一个字节或字符后,移到下一个字节并等待。重要的是ReadChar并不关心读到字节是否是0,它将返回一个空字符串给Lingo交移到下一个字节。奥古多媒体G"z{ m;[O$n
奥古多媒体%K4@4g;\ B2R dvu$v S
  二进制数据
uM4I`*HWci!Cc0 奥古多媒体z]hn/E{ w mh
  现在我们有办法知道文件中有多少字节,也能够读取每一个字节了。接下来的事情是什么数据是我们所需要的。如果我们保存所有读取到的字节,问题不亚于用ReadFile函数了。在Lingo中,0字节等同于empty,或者" ",在字符串中不会增加任何东西。奥古多媒体%S.tfA|k/V]%X!b!f
奥古多媒体5D"|kg1X;?!QS&M
  很明显的变通办法是将所有读出的数据作为一个字符串保存在线性列表里(也有其它办法,例如使用Image object),再由CharToNum函数将这些字符串数据转换成数字。这样,文件中每个字节的值都可加入线性列表中,我们就可以操作这些数据了。下面是其代码:奥古多媒体r^D,k1n

UGGL?L^0 on readBinaryFile filePath
g#fZm2]0 -- Call handler using the full file path奥古多媒体 JD(AK/p:\

Ei0dsnB2K]*m0 byteList = []奥古多媒体I xq7S3v+J c
-- This list will contain all of the byte values retrieved
:_,V,u rzzc Jk0 fileObj = new(xtra "fileIO")
2]8g7xx S2]hCw{0 fileObj.openFile(filePath, 1)奥古多媒体+LWU!~Yw[,X%I
-- Open the file with read-only access
6\`ba+E L7c*Js,G*[*sz0
~9~yG\0 if fileObj.status() = 0 then
J$P[(PS7`9_:S0 fileLength = fileObj.getLength()奥古多媒体9sJ M/^BI _ sD)^
-- Find the length of the file in bytes奥古多媒体}?]]T9RV*` s
repeat with index = 1 to fileLength
!jM;t1s^a9w.iXI0 byteList.append(charToNum(fileObj.readChar()))奥古多媒体n4e4^,el`m
-- Append the value of each byte of the file to byteList
"U8N ^,}6ohk t4r0 end repeat奥古多媒体%W8d\C]/Q
end if
x,boGk_6?0
o;@s(d];R cy#Z0 fileObj.closeFile()奥古多媒体$iHG)vu
-- Close the file
8^/Kj-ft6Nv0 fileObj = 0
,Ft8WZ!C VS;i$Ul0 -- Clear the FileIO instance from memory
W"X B0Z%DS S^0 return byteList
1LkY0Y5D P0 奥古多媒体:B\5@U4f0qs6y]b
end
8MWr m*{0 奥古多媒体h i)}U l-m1H-`"r
  关键在于弄清Repeat循环,结合使用ReadChar函数,让FileIO保持从文件中读取数据,不管所遇到的字符值。这样我们就有办法完整地读取任何文件。奥古多媒体`N#F-B3B%aw+Z,r

.G ZUb d;P&M0   读取长文件
8z;N tMM0
/V)Hi#@[JJ.Byi8E PG0   你会想到的一个问题是,使用readBinaryFile程序读取长文件时会返回一个极大的byteList 变量,占用许多内存。假如我们知道哪部分数据是我们想要的,可以这样作轻微的修改。奥古多媒体Il-U|,`7z#A'x0^

#k1dZW9GD0 on readBinaryFile filePath, startByte, endByte
FOxV2yM3M a0 -- Optional parameters for specifying positions in the file奥古多媒体E5k_A|k`9d
byteList = []
R.]+t5fpo\0 fileObj = new(xtra "fileIO")
aA/R0XfAB9MJ l0 fileObj.openFile(filePath, 1)
7dxmR:bH1b6J0 奥古多媒体/AdKD lR N4`&PV
if fileObj.status() = 0 then
#e)y+Llk*@%H$U7g_0 fileLength = fileObj.getLength()奥古多媒体`f c#\[1D(z}

p~|d(Fw L `,O2A0 if startByte.voidP then奥古多媒体L,DB |a*W%bQ
-- Read entire file if parameters aren't supplied奥古多媒体_ \Bh(R!ZC
startByte = 1奥古多媒体d$tJ]$a(` k n7W[
endByte = fileLength
F PVjh;n v0 end if
1c-S5Tc ^8vh~:F0 奥古多媒体mi}UcZK
奥古多媒体)dT%eqd"C1^CB
if (fileLength >= startByte) and (fileLength >= endByte) then奥古多媒体2s$u^$\6n_3xp._
fileObj.setPosition(startByte-1)
p1JT)FLo0 -- Position FileIO to read from the correct point in the file奥古多媒体.Wz/YOxi$]
repeat with index = startByte to endByte奥古多媒体lMD$IzHJXA
byteList.append(charToNum(fileObj.readChar()))奥古多媒体 ?'n6R{5cNjr c
end repeat奥古多媒体lX.NSJLu%Z
end if奥古多媒体0IW4Q8X[ d1Y:N
end if 奥古多媒体 l3W/x}8r i2x/l4Mf;N
奥古多媒体O~jc7_`i
fileObj.closeFile()奥古多媒体i8R7Z|\6w
fileObj = 0
5I Z?,cIN.y0 return byteList奥古多媒体?5r.FM%C Vx?(?
end 奥古多媒体4a5J:] ]1J6K

oM(rP;ii0   例子:读取MP3标签奥古多媒体2a,_1` a~

5Xt/K@'Y:C0   使用这个程序的真实例子是读取MP3文件标签。MP3文件标签存储在最后的128个字节中。本例子包含有一个Director movie,说明是如何做到这一点的(需要FileXtra和FileIO Xtra)。关于文件格式,可参考www.wotsit.org
6i"k}[5K0 奥古多媒体/J2H2}w`+z:o
  此例子程序从MP3文件中读取了诸如歌名、歌手、专辑名、年份、风格等信息。奥古多媒体 [F3E:U%vi4XQ\

J9IK MCbT nyq`0 on readMP3tags filePath
Z$Y$e&{m n0mX0
B!BAEn S"WWD0 fileLength = getFileSizeInBytes (filePath)
H/s5^3k4`-Tn%R0 if fileLength > 0 then
a!Yhb"L zEg*jE0 byteList = readBinaryFile (filePath, fileLength - 127, fileLength)奥古多媒体U'Ys`'^9iOA8T
tagStr = ""
/Jg'YFm @r5i0 repeat with index = 1 to byteList.count奥古多媒体r6c1QPrG&IaR
tagStr = tagStr & numToChar (byteList[index])
:Jb#i-MSx2E7DL8M0 end repeat奥古多媒体|5}cUo:A5w5Q
奥古多媒体:r9n _ e J;V#l\p.f
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)]
A~TG&[&Rm Ax0
Z(U.E ZX%C0 repeat with index = 1 to tags.count奥古多媒体0Tdp7GGw(j%K V
memberName = string (tags.getPropAt (index))奥古多媒体h9jg[@~\5Y(w
newText = clipString (tags[index])
{U8I6N+K] ~)t0 member (memberName).text = newText奥古多媒体9f(M#fT`TA(u7|
end repeat奥古多媒体3@.^v6h4v[
end if奥古多媒体 |u:Zr?_R&C
奥古多媒体C/bt*iZ#nP&ONQ ^
end奥古多媒体\HC]3D5nj4k

2c6w9_W8o9~N0 相关附件
顶:9 踩:12
对本文中的事件或人物打分:
当前平均分:0.11 (56次打分)
对本篇资讯内容的质量打分:
当前平均分:0.65 (51次打分)
【已经有56人表态】
11票
感动
6票
路过
9票
高兴
6票
难过
5票
搞笑
5票
愤怒
5票
无聊
9票
同情
上一篇 下一篇

网络资源


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