现在的位置: 首页 > 综合 > 正文

VB6二进制双通道技术实战经典

2013年06月10日 ⁄ 综合 ⁄ 共 6267字 ⁄ 字号 评论关闭

时间:2000/10/12 18:14 作者:新天

  (一)编程原理:

  文件分割实际上就是将目标文件用二进制读写的方法,精确的连续保存为合适大小的独立文件,一般来说,分割后的文件在正确组装前是不能被使用的。

  文件还原是文件分割的逆过程,即是将分割后的文件严密的按照分割顺序用二进制读写的方法写入一个同一个文件的过程,只要程序算法和逻辑正确严密,分割前和分割后的文件是没有一个字节的差别的。

  之所以使用双通道技术是因为当被分割的文件较大或者非常大(远远大于内存)时,使用单个文件通道定义的内存二进制缓冲数组非常容易造成内存的用尽而导致操作失败,另一方面,它的处理速度和可靠性也是非常令人担忧的。

  编程思路是,首先使用双通道技术将目标文件分割成指定大小的文件,扩展名依次是“指定文件名+.源文件扩展名+.分割序号”,并且生成一个还原信息文件“被分割文件名.hj”,该文件将记录文件分割的有关信息;文件还原时,同样利用双通道,按照在还原信息文件中登记的信息,将待还原的文件写入同一个文件中。

  (二)编程实践:

  (1)启动vb6,建立一个标准exe工程,添加一个窗体form1,添加microsoft common dialog control 6.0控件,命名为cod1;添加两个frame控件(frame1的caption=“文件分割”,frame2的caption=“文件还原”);添加五个标签框,caption属性依次为“被分割文件名”、“分割后文件大小”、“分割后文件保存在”、“单位:bytes字节”、“还原信息文件名”、“还原后文件保存在”;由上至下一次添加四个caption=“浏览...”的命令按钮command1、command2、command3、command4;由上至下依次添加5个textbox按钮txtFileName、txtFileLength、Txtoutname、txtTemplateName、txtOutputFile;添加两个命令按钮cmdsplit,caption=“开始分割”、cmdunsplit,caption=“开始还原”;两个命令按command5、command6用来指示操作执行进度。代码如下:

  Option Explicit

  Private Sub cmdSplit_Click() ’文件分割

  Dim err_descr As String ’定义接收返回错误码的字符串变量

  If Not SplitFile(txtFileName.Text,0,err_descr,CLng(txtFileLength.Text),Txtoutname.Text) Then

  MsgBox "文件操作产生了错误——" & err_descr,vbExclamation

  Else

  MsgBox "文件分割操作已经圆满完成!"

  End If

  End Sub ’当splitfile公用过程返回值=true表示操作成功,否则失败并返回错误简短的提示

  Private Sub cmdUnsplit_Click() ’文件还原

  Dim err_descr As String

  If Not ReassembleFile(txt TemplateName.Text,False,txtOutputFile.Text) Then

  MsgBox "文件操作产生了错误——" & err_descr,vbExclamation

  Else

  MsgBox "文件还原操作已经圆满完成!"

  End If

  End Sub ’当ReassembleFile公用过程返回值=true表示操作成功,否则失败并返回错误简短的提示

  Private Sub Command1_Click() ’选择被分割文件

  CoD1.Filter="所有格式文件*.*|*.*"

  CoD1.ShowOpen

  If CoD1.FileName<>"" Then

  txtFileName.Text=CoD1.FileName

  End If ’如果未选中文件就退出过程

  End Sub

  Private Sub Command2_Click() ’分割后文件保存路径名称

  With CoD1

  If txtFileName.Text="" Then

  MsgBox "请首先选择一个被分割文件!"

  Exit Sub

  End If ’如果未选定被分割文件退出过程

  .ShowSave

  If .FileName<>"" Then

  Txtoutname.Text=.FileName

  End If ’如果未指定保存文件名退出

  End With

  End Sub

  Private Sub Command3_Click() ’传回还原信息文件名

  With CoD1

  .FileName=""

  .Filter="还原信息文件*.hj|*.hj" ’只显示*.hj还原信息文件

  .ShowOpen

  If .FileName<>"" Then

  txtTemplateName.Text=.FileName

  End If

  End With

  End Sub

  Private Sub Command4_Click() ’得到并计算还原后文件名、扩展名

  Dim g

  With CoD1

  If txtTemplateName.Text="" Then

  MsgBox "请首先选择一个还原信息文件!"

  Exit Sub ’如果还原信息文件未被选中,则退出过程

  End If

  .Filter=""

  .FileName="" ’清空过期文件名和类型指针

  .ShowSave

  If .FileName<>"" Then

  g=InStr(1,txtTemplateName.Text,".") ’查找第一个“.”

  txtOutputFile.Text=.FileName & Mid

  (txtTemplateName.Text,g,4) ’返回文件的用户指定名称和原扩展名

  End If

  End With

  End Sub

  Private Sub Form_Load()

  Me.Left=(Screen.Width-Me.Width)/2

  Me.Top=(Screen.Height-Me.Height)/2 ’窗体居中

  Me.Caption=App.Title ’初始化标题栏

  End Sub ’主程序结束

  (2)添加一个模块Module1,其中包含各种算法具体实现过程,双击模块写入以下代码:

  Type FileSection

  Bytes() As Byte

  End Type ’定义实际内存数组

  Type SectionedFile

  Files() As FileSection

  End Type ’定义辅助内存数组,以备扩展使用

  Type FileInfo

  OrigProjSize As Long ’文件大小

  OrigFileName As String

  FileCount As Integer

  FileStartNum As Long

  End Type ’定义还原信息文件结构参数

  Public Function SplitFile(SplitFileName As String,BeginningNumber As Long,ReturnErrorDes As String,Split As Long,oName As String) As Boolean

  ’定义公有过程,用来分割文件,函数返回一逻辑值。true代表成功,false代表失败,四个参数依次是,被分割文件名,开始编号,分割后文件大小,分割后文件名称

  Dim SaveName As String ’分割后文件名

  Dim fnum As Integer,fnum1 As Integer ’文件通道变量

  SplitFile=True ’如果下面没有错误,返回真值

  On Error GoTo CleanUp

  Dim CurrentFile As SectionedFile,m_lngNumFil As Long,m_LngLoop As Long,FilesLen As Long

  FilesLen=FileLen(SplitFileName) ’得到被分割文件大小

  If FilesLen <= Split + 1 Then

  SplitFile=False

  ReturnErrorDes="被分割文件大小小于分割后文件大小,请重新设置!"

  Exit Function

  End If ’如果被分割文件小于分割后文件,退出过程

  fnum=FreeFile ’返回第一个空闲通道用来读取

  Open SplitFileName For Binary As fnum ’用二进制方式打开被分割文件

  If CInt(FilesLen/Split)>=FilesLen/Split Or CInt(FilesLen/Split)=FilesLen/Split Then

  m_lngNumFil=CInt(FilesLen/Split)

  Else

  m_lngNumFil=CInt(FilesLen/Split)+1

  End If ’精确计算文件将被分割的个数

  ReDim CurrentFile.Files(1) ’分配一个内存辅助数组

  For m_LngLoop=1 To m_lngNumFil

   ’这个循环用来将文件分割,并且生成分割后的文件

  If m_LngLoop < m_lngNumFil Then ’如果不是最后一次循环

  ReDim CurrentFile.Files(1).Bytes(1 To Split)

  ’ 重新分配大小等于分割尺寸的内存数组

  Get #fnum,,CurrentFile.Files(1).Bytes

  ’读取等于分割大小的二进制数据到内存数组

  Else ’如果是最后一次循环

  ReDim CurrentFile.Files(1).Bytes To FilesLen-((m_lngNumFil-1)*Split))

  ’重新分配大小等于遗留长度的内存数组

  Get #fnum,,CurrentFile.Files(1).Bytes

  Close #fnum ’关闭读取文件通道

  End If

  SaveName=oName & "." & Format(BeginningNumber-1+m_LngLoop,"00#") ’计算分割后的文件名,扩展名为00?

  fnum1=FreeFile ’得到第二个空闲通道用来写入

  Open SaveName For Binary As fnum1

  Put #fnum1,1,CurrentFile.Files(1)

  DoEvents

  Close #fnum1 ’用二进制方式写入分割后的文件

  Form1.Command6.Caption=FormatPercent(m_LngLoop / m_lngNumFil) ’显示简单的进度指示

  Form1.Command5.Caption=SaveName ’显示正在操作的文件名

  Next

  Dim FileInfoFile As FileInfo ’定义还原信息文件内容

  FileInfoFile.FileCount=m_lngNumFil ’分割后文件个数

  FileInfoFile.OrigFileName=oName ’输出文件名

  FileInfoFile.OrigProjSize=FileLen(SplitFileName) ’被分割文件大小

  FileInfoFile.FileStartNum=BeginningNumber ’分割后文件起始编号

  SaveName=oName & ".HJ" ’还原信息文件名

  fnum=FreeFile

  Open SaveName For Binary As #fnum

  Put #fnum,,FileInfoFile

  Close #fnum ’写入还原信息文件

  Exit Function

  CleanUp: ’如果出现错误

  ReturnErrorDes=Err.Description

  SplitFile=False ’返回值为false

  End Function

  PublicFunctionReassembleFile(Template FileName As String,Optional UseOldFilenameAsBoolean=True,OutPutName as string)As Boolean ’定义文件还原操作公用过程

  On Error GoTo e

  Form1.MousePointer=11

  Dim FileInfo As FileInfo,outname As String,File As SectionedFile,m_LngLoop As Long,OpenName

  Dim fnum As Integer,fnum1 As Integer

  ReassembleFile=True

  fnum=FreeFile

  Open TemplateFileName For Binary As #fnum

  Get #fnum,,FileInfo

  Close #fnum ’读取还原信息文件的有关内容

  If UseOldFilename Then

  outname=FileInfo.OrigFileName

  Else

  outname=OutPutName

  End If ’是否自己指定还原后文件名

  ReDim File.Files(1)

  fnum1=FreeFile

  Open outname For Binary As #fnum1

  For m_LngLoop=1 To FileInfo.FileCount

  ’通过还原信息中记载的文件个数确定读取次数

  OpenName=FileInfo.OrigFileName & "." & Format((FileInfo.FileStartNum-1+m_LngLoop),"00#")

  ’得到分割后生成的文件名称、路径

  fnum=FreeFile

  Open OpenName For Binary As #fnum

  Get #fnum,1,File.Files(1)

  Close #fnum ’读取

  Put #fnum1,,File.Files(1).Bytes ’写入

  Form1.Command6.Caption=FormatPercent(m_LngLoop/FileInfo.FileCount)

  Form1.Command5.Caption=OpenName

  Next

  Close #fnum1

  Form1.MousePointer=0

  Exit Function

  e:

  MsgBox "文件操作产生了错误:" & Err.Description,vbExclamation

  ReassembleFile=False

  Form1.MousePointer=0

  End Function

  (三)运行调试:

  首先通过浏览指定被分割文件名、分割后文件大小、分割后文件名或者还原信息文件名、还原后文件名,然后点击开始分割或者开始还原即可,该程序算法严谨,但是,为了保留一定的扩展能力和对以往源代码的兼容性,也存在一些冗余代码,读者尽可以根据自己的喜好进行改进。另外,使用vb5的朋友注意了,本文函数FormatPercent函数只能在vb6中使用,它的作用是将一个表达式转化成百分数,你必须采用其他的变通方法,其他代码全部通用。 
 

抱歉!评论已关闭.