音乐台自动备份系统软件开发部分详解.docx
《音乐台自动备份系统软件开发部分详解.docx》由会员分享,可在线阅读,更多相关《音乐台自动备份系统软件开发部分详解.docx(22页珍藏版)》请在冰豆网上搜索。
音乐台自动备份系统软件开发部分详解
音乐台自动备份系统软件开发部分详解
安徽人民广播电台系列台之一的安徽音乐台音频工作站系统采用了WindowsNT平台构架。
服务器操作系统是WindowsNTServer,工作站使用了WindowsNTWorkStation。
音频软件平台使用了Dalet系统,这套系统的后台数据库使用了Sybase。
为了保证节目安全播出,我们采用了网络主播、本地备播的安全措施。
但是这样一来,为了保证网络节目内容与本地内容一致,必须每天都将网络数据库和必要的播出节目文件备份到本地播出机器,工作量非常大。
为了节约有限的人力资源;使得工作更加高效,我们开发了一套自动备份系统。
本系统的数据库部分利用了Sybase数据库和SQL语句等等。
但是要使得备份工作自动运行,我们只有采用编程的方法。
下面就将我们所写的软件做一详细的介绍。
编程部分主要考虑两个部分:
一、在固定的系统时间里运行。
这是为了备份不占用人力,而且由于一般备份都在使用者没有实际工作的时候(一般在晚间的11:
00以后)。
二、备份音频文件。
由于节目在大部分时候都是不断更新的,这就要求程序在运行期间能够自动识别哪些音频文件在目标位置已经存在,哪些不存在的判断要求。
好了下面就是这两个软件开发的全过程(本程序在VisualBasic6.0下开发,在WindowNT操作系统中调试通过)。
一、RunInTime(定时运行程序)
a)准备知识:
程序要求调用系统时间并且扫描系统时间,以待定时调用其他需要运行的部分。
b)程序结构图:
c)源程序剖析:
1.在VisualBasic6.0中新建一工程(此工程带有一个窗体对象Form1.frm)。
控件名称
控件类别
初始化属性
功能说明
Form1
Form
BorderStyle=1-FixedSingle;Caption=”音乐台远程自动备份工具”;Icon:
使用相应的图标
工作时显示的窗体
brwbut
CommandButton
Caption=”添加任务”
“添加任务”按扭
Check1
CheckBox
确定是否在外部程序中调用当前的星期标识
Command1
CommandButton
Caption=”取消&&退出”
“取消&退出”按扭
Command2
Label
Caption=”隐藏”
“隐藏”热点按扭
Command3
CommandButton
Caption=”移除任务”
“移除任务”按扭
CommonDialog1
CommonDialog
公共对话框(需要引用部件)
Label1
Label
Caption=”时”
显示信息
Label2
Caption=”分”
Label4
Caption=”设置定时”
Label5
Caption=”确定星期”
Label6
Caption=”运行程序列表:
”
Label3
Caption=””
显示当前时间
minCom
ComboBox
调整分钟的组合框
hourCom
ComboBox
调整小时的组合框
okbut
CommandButton
Caption=”确定”
“确定”按扭
Picture1
PictureBox
Picture:
使用相应的图标
后台运行时在任务栏上的图标
shelltext
ListBox
Height=210
显示要运行的任务的列表
Timer1
Timer
Interval=1000
监测时间并在适当时触发应用程序
Timer2
Timer
Interval=1000
监测时间并在Label3上显示当前时间
2.在窗体中加载下列控件:
3.源程序:
声明API函数使用的类型:
用于任务栏图标的显示和隐藏
PrivateTypeNOTIFYICONDATA
cbsizeAsLong'本结构的大小
hwndAsLong'接受图标回传消息的窗口句柄
uidAsLong'图标标识
uFlagsAsLong'回传给窗口的消息
ucallbackmessageAsLong'图标句柄
hiconAsLong
sztipAsString*64'当鼠标停留在图表上时出现的提示
EndType
定义API函数使用的常量:
PrivateConstnim_add=&H0
PrivateConstnim_delete=&H2
PrivateConstwm_mousemove=&H200
PrivateConstnif_message=&H1
PrivateConstnif_icon=&H2
PrivateConstnif_tip=&H4
声明API函数:
PrivateDeclareFunctionShell_NotifyIconLib"shell32"Alias"Shell_NotifyIconA"(ByValdwmessageAsLong,pnidAsNOTIFYICONDATA)AsBoolean
定义本程序使用的全局变量:
DimtAsNOTIFYICONDATA'定义自定义类型的变量
DimHAsInteger
DimMAsInteger
DimAAsString
DimnwAsString
DimnsnAsString
添加按扭的程序段:
PrivateSubbrwbut_Click()
CommonDialog1.ShowOpen'打开公用对话框,用于显示需要选择的程序
IfCommonDialog1.FileName<>""Then'判断选择是否正确以便加入列表框
shelltext.AddItemCommonDialog1.FileName
shelltext.Height=shelltext.ListCount*210
EndIf
EndSub
取消退出按扭的程序段:
PrivateSubCommand1_Click()
UnloadMe
EndSub
隐藏按扭的程序段:
PrivateSubCommand2_Click()
Me.WindowState=vbMinimized
EndSub
定义隐藏按扭为热区按扭:
PrivateSubcommand2_MouseMove(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)
command2.ForeColor=RGB(255,0,0)
EndSub
移除按扭的程序段:
PrivateSubCommand3_Click()
shelltext.RemoveItemshelltext.ListIndex
shelltext.Height=shelltext.ListCount*210
Ifshelltext.ListCount=0Then
Command3.Enabled=False
EndIf
EndSub
窗体载入的程序段:
PrivateSubForm_Load()
Picture1.Visible=False
Command3.Enabled=False
CommonDialog1.Filter="批处理文件|*.bat|可执行文件|*.exe|所有文件|*.*"
Fori=0To23
hourCom.AddItemi
Next
Fori=0To59
minCom.AddItemi
Next
hourCom.Text=Hour(Now)
minCom.Text=Minute(Now)
command2.Visible=False
EndSub
定义热区按扭的响应:
PrivateSubForm_MouseMove(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)
command2.ForeColor=RGB(255,255,255)
EndSub
定义在改变窗体大小(这里特指最小化)时任务栏的变化:
PrivateSubForm_Resize()
IfMe.WindowState=vbMinimizedThen
t.cbsize=Len(t)
t.hwnd=Picture1.hwnd
t.uid=1&
t.uFlags=nif_iconOrnif_tipOrnif_message
t.ucallbackmessage=wm_mousemove
t.hicon=Picture1.Picture
t.sztip="点击后显示窗口"&Chr$(0)
Shell_NotifyIconnim_add,t
Me.Hide
EndIf
EndSub
定义小时选择组合框改变事件:
PrivateSubhourCom_Change()
IfhourCom.Text>23OrhourCom.Text<0Then
hourCom.Text="0"
EndIf
EndSub
定义分钟选择组合框改变事件:
PrivateSubminCom_Change()
IfminCom.Text>59OrminCom.Text<0Then
minCom.Text=0
EndIf
EndSub
确认按扭:
PrivateSubokbut_Click()
Ifshelltext.ListCount=0Then
MsgBox"您的列表中没有项目"
Else
command2.Visible=True
H=Val(hourCom.Text)
M=Val(minCom.Text)
Timer1.Enabled=True
EndIf
EndSub
在窗体最小化时的鼠标显示字符:
PrivateSubPicture1_MouseMove(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)
IfMe.WindowState<>vbMinimizedThen
ExitSub
EndIf
If((ButtonAndvbLeftButton)>0)Then
t.cbsize=Len(t)
t.hwnd=Picture1.hwnd
t.uFlags=nif_icon
t.uid=1&
Shell_NotifyIconnim_delete,t
Me.WindowState=vbNormal
Me.Show
EndIf
EndSub
选择列表框中的项目:
PrivateSubshelltext_Click()
Command3.Enabled=True
EndSub
判定当前时间与设定时间以便调用外部程序:
PrivateSubTimer1_Timer()
SelectCaseWeekday(Now)'定义星期参数和显示星期
Case2
nw="Monday"
nsn="一"
Case3
nw="Tuesday"
nsn="二"
Case4
nw="Wednesday"
nsn="三"
Case5
nw="Thursday"
nsn="四"
Case6
nw="Friday"
nsn="五"
Case7
nw="Saturday"
nsn="六"
Case1
nw="Sunday"
nsn="日"
EndSelect
IfH=Hour(Now)AndM=Minute(Now)Then'判定当前时间和设定时间是否吻合
Fori=0Toshelltext.ListCount-1
A=shelltext.List(i)
IfCheck1.Value=0Then
X=Shell(A)
ElseIfCheck1.Value=1Then
X=Shell(A&Space
(1)&nw,vbHide)'调用列表框中的外部程序并在后台运行
EndIf
Next
Timer1.Enabled=False'终止Timer1使得同一程序不会重复执行
EndIf
EndSub
采集当前时间并显示出来:
PrivateSubTimer2_Timer()
IfHour(Now)>=10Then
nh=Hour(Now)
Else
nh="0"&Hour(Now)
EndIf
IfMinute(Now)>=10Then
nm=Minute(Now)
Else
nm="0"&Minute(Now)
EndIf
IfSecond(Now)>=10Then
ns=Second(Now)
Else
ns="0"&Second(Now)
EndIf
Label3.Caption=Year(Now)&"年"&Month(Now)&"月"&Day(Now)&"日"&Chr(10)&"星期"&nsn&Chr(10)&nh&":
"&nm&":
"&ns
IfM<>Minute(Now)Then
Timer1.Enabled=True'Timer1的执行时间过后继续监测系统时间
EndIf
EndSub
在上面的程序中有几点需要指出:
1.Picture控件只用于在系统任务栏显示图标。
2.注意Timer1和Timer2的有效期——Timer2始终有效,Timer1在系统时间与检测时间相同时无效,保证外部程序不会在同一时间叠加重复执行,避免死循环。
3.按扭的可用性保证用户不会由于误操作造成程序出错(这里没有使用错误处理语句)。
二、BackSon(音频文件备份工具)
a)编程思想
首先要考虑这样几个问题:
i.由于音频库中的音频文件数量巨大,而在平时的播出中只使用了极少的文件,所以只需要将平时必要的栏目文件备份即可(这里使用了SQL技术收集需要备份的文件名,我们将其做成文本文件C:
\TEMP\source.txt)。
ii.需要收集曾经备份过的文件名称(存放在C:
\TEMP\target.txt),与Source.txt比较以后可以取得部分尚未备份过的文件名称(存放在C:
\TEMP\temp.txt),使得只需要备份最新制作的音频文件,避免了计算机重复劳动。
iii.为了方便查询在备份以后具体有多少、是哪些文件被复制,需要保留这些临时文件,并且建立了C:
\TEMP\count.txt文件存放备份文件的数目。
iv.为了确定源位置和目标位置,需要调用文件夹位置,且当文件夹位置改变后方便更新,制作了C:
\WINNT\config.ini文件存放位置字符传。
v.由于有这种特殊情况:
文件名没有改变,但是文件内容改变了,需要重新备份。
加入了文件比较函数对同名文件的大小进行比较,进一步确定是否需要备份。
考虑了上述问题可以理解下面的流程图:
上述流程图是整个程序的主线比较简单,但是在其中的一些子函数中有部分细节还需要仔细琢磨:
a.在一开始的文件存在判定中还需要增加判定过程FileExists,才能具体判断是否存在所需文件。
b.没有必要的Config.txt文件时,需要建立Config.txt,调用了Form1窗体引导用户自己建立文件,而Form1的触发事件不易与引导模块建立交互关系,所以部分语句需要在Form1的事件中重复使用。
c.由于音频文件的格式是Mpeg1的第二层,文件扩展名为.SND,所以在扫描目标位置的音频文件时需要针对这样的扩展名来建立Target.txt。
d.建立需要拷贝文件列表文件Temp.txt时需要做一些比较工作,这里除了需要对文件名比较外还需要对文件的大小做测试,所以在CopyF中需要调用CompareF函数做同名文件是否完全相同的比较。
这些细节在源程序中都已经考虑到了,下面给出所有的源代码:
工程文件中使用了三个部分——其中两个窗体Form1(form1.frm),Form2(form2.frm);一个启动模块(主程序)Module1(main.bas)。
Module1(main.bas)的源代码如下:
声明程序的全局变量和常量:
PublicConstSouTxt="c:
\temp\source.txt"
PublicConstTarTxt="c:
\temp\target.txt"
PublicConstTempTxt="c:
\temp\temp.txt"
PublicConstConfig="c:
\winnt\config.ini"
DimNoAsInteger'No为通用的文件号
PublicPathSAsString
PublicPathTAsString
PublicnAsNewCollection'集合对象n的目的是为了建立数目文件Count.txt使用的
主过程(引导过程):
PublicSubMain()
DimfExistAsBoolean'判定Config.txt是否存在
fExist=FileExists(Config)
IffExistThen
No=FreeFile
OpenConfigForInputAs#No
Input#No,PathS,PathT
Close#No
'BuildFSouTxt,PathS
BuildFTarTxt,PathT'建立Target.txt和Temp.txt文件
BuildTempSouTxt,TarTxt,TempTxt
CopyFPathS,PathT,TempTxt'调用复制文件过程
Else
Form1.Show'如果Config.txt不存在,则调用Form1建立Config.txt
EndIf
EndSub
建立文件过程:
PublicSubBuildF(fileNAsString,SoundFilePathAsString)
DimXAsString
No=FreeFile
X=Dir(SoundFilePath,vbNormal)'遍历整个文件夹取得扩展名为.snd或.SND的文件名
OpenfileNForOutputAs#No
DoWhileX<>""
IfRight$(X,4)=".snd"OrRight$(X,4)=".SND"Then
Write#No,X'将文件名字符串放入所建立的文件中
EndIf
X=Dir
Loop
Close#No
EndSub
比较文件大小是否相同的函数:
PublicFunctionCompareF(nameAsString)AsBoolean
OnErrorResumeNext'排除数据库有记录但是文件已经不存在的特殊情况
IfFileLen(PathS&name)=FileLen(PathT&name)Then
CompareF=True'如果相同则返回True,否则返回False
Else
CompareF=False
EndIf
EndFunction
复制文件过程:
PublicSubCopyF(SouPathAsString,TarPathAsString,ListFileAsString)
Form2.Show'显示Form2
DimuseNameAsString
No=FreeFile
OpenListFileForInputAs#No'取得所有需要复制文件的个数存入Count.txt中
DoWhileNotEOF(No)
Input#No,useName
n.AddX
Loop
Close#No
Form2.ProgressBar1.Max=n.Count+1
No=FreeFile
Open"c:
\temp\count.txt"ForOutputAs#No
Write#No,n.Count
Close#No
Form2.ProgressBar1.Min=0
Form2.ProgressBar1.Value=0
No=FreeFile
OpenListFileForInputAs#No'读取记录复制文件
DoWhileNotEOF(No)
Input#No,useName
OnErrorResumeNext
FileCopySouPath&useName,TarPath&useName
Form2.ProgressBar1.Value=Form2.ProgressBar1.Value+1
Loop
Close#No
UnloadForm2'复制完成后卸载Form2
EndSub
如有必要可以删除目标位置的文件(略):
PublicSubDelF()
……
EndSub
文件是否存在的判定函数:
PublicFunctionFileExists(fNameAsString)AsBoolean
DimfAsInteger
OnErrorResumeNext
f=FreeFile
OpenfNameForInputAs#f
IfErr=0Then
FileExists=True'存在返回True,否则返回False
Else
FileExists=False
EndIf
Close#f
EndFunction
建立Temp.txt文件的函数:
PublicSubBuildTemp(SourceAsString,TargetAsString,TempAsString)
DimSAsInteger
DimTAsInteger
DimTmpAsInteger
DimItemSourceAsString
DimItemTargetAsString
DimFinAsBoolean
Tmp=