读书人

VB有关问题,超级初学者加白痴新手(从来

发布时间: 2012-03-03 15:33:02 作者: rapoo

VB问题,超级菜鸟加白痴新手(从来都没写过的刚买了本VB才开始看),想写一个小程序,希望能够完成以下功能。求指导。
程序段包含的功能基本上就是文件同步.通过 "文件时间信息(GetFileTime?) "和 "文件大小信息(GetFileSize?) ",以及文件是否存在这三项进行判断.判断后,将需要同步的文件拷贝到目标目录.
-------------------------------------------------------
基本思路如下:
1.从 "源路径 "以生成一个列表文件的方式,将 "源路径 "下的所有文件的信息读取并保存下来(应该包含1.文件时间信息(FTime1) 2.文件大小信息(FSize1) 3.文件路径及文件名(FPath1,格式例如:X:\XXX\XXX.XXX)).假设该文件名为FileA.同样的根据 "目标路径 "也生成这么一个文件.假设文件名为FileB,包含的信息为FTime2/FSize2/FPath2.
2.将FileA文件与FileB文件进行对比判断.将判断结果保存到一个文件(假设文件名为:FileC,而该文件中只要包含文件的 "源路径 "/ "目标路径 "和一个判断标记就可以.).最后按照FileC中的记录.对文件进行操作.
--------------------
判断中的思路如下:(分四种情况,进行两次判断.)
1.首先是文件是否存在判断,分为以下三种:一, "源路径 "有而 "目标路径 "没有,判断标记为C(拷贝).二, "源路径 "没有而 "目标路径 "有,判断标记为D(删除).三, "源路径 "有而 "目标路径 "也有,那么进行第二次判断.
2.执行第二次判断.判断条件为将FTime1/FSize1与FTime2/FSize2(后面标记为2的两个变量为 "目标路径 "中的文件,那么同样也要生成 "目标路径 "下的所有文件的一个表格,假设文件名为FileB,同样包含FTime/FSize/FPath三项信息)进行对比,产生以下两种结果:一,两组变量都一致,那么判断标记为U(不操作).二,判断结果为不一致(两者只要有一个不一致就算),那么判断标记为C(拷贝).
----------------------
那么最后,根据FileC中的信息,对文件执行U(不操作)/C(拷贝)/D(删除)等操作,对于判断标记为U的,可以不保存,这样可以缩短程序运行时间.而对于判断标记为C或D的文件,根据FPath1和FPath2来执行操作.例如:FileCopy_FPath1_FPath2 或 Kill_FPath2 来拷贝和删除.
----------------------
综上所述,由于小弟没学过编程,如何才能用VB语言实现以上的功能,希望大家能够给予指导和帮助,提出一些建议或思路,当然也可以有其他的思路,只要能完成以上功能,至于实现功能的方法不限制,但要求是用VB(我全部的学习编程的资料就一本23.00元的VB程序自学书).
至于其中的根据文件大小/日期等信息用生成文件来进行文件对比啊,用FileCopy/Kill来执行操作啊这些,都可以提出其他的思路和实现方法,只要程序跑得好,用API或用VB自己提供的语句都可以.不知道API有没有比较好用的方法来实现文件相关信息(指文件大小,文件日期与时间,文件是否存在等)的对比.
------------------------
总之,希望能够得到大家的指导和帮助.小弟初学编程,又是第一次发帖,有些地方如果看不明白,请指出来.我等候大家的回复.谢谢.感激不尽.

[解决办法]
建议:
1 源文件和目标文件列表没有必要用文件保存,用不可见的 ListBox 控件会更快速方便。
2 既然日期和大小之一不相同就更新,可以将两项合成一个参数,比较更加方便。

'Put 2 ListBox on your form, which named as lstSrc and lstDst

Declare Function CreateFile Lib "kernel32 " Alias "CreateFileA " (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

Public Const GENERIC_WRITE = &H40000000

Public Const FILE_SHARE_READ = &H1

Public Const OPEN_EXISTING = 3

Public Const FILE_ATTRIBUTE_NORMAL = &H80

Private Declare Function GetFileTime Lib "kernel32 " Alias "GetFileTime " (ByVal hFile As Long, lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As FILETIME) As Long

Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Declare Function SendMessagebyString Lib _
"user32 " Alias "SendMessageA " (ByVal hWND As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lParam As String) As Long
Private Const LB_FINDSTRINGEXACT = &H1A2 '在 ListBox 中精确查找

Private Sub Update_File(Byval strSrcPath As String, Byval strDstPath As String)
Dim strFilename As String
Dim CreationTime AS FILETIME, AccessTime AS FILETIME, WriteTime AS FILETIME
Dim lngFileFlag As Long, hFile As Long, i As Integer, lngIndex As Long

'Get source files
strFilename = Dir(strSrcPath & "\*.* ")
Do Until strFilename = " "

hFile = CreateFile(strFilename, GENERIC_READ, _
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
Call GetFileTime (hFile, CreationTime, AccessTime As FILETIME, WriteTime)


CloseHandle hFile

lngFileFlag = CreationTime.dwLowDateTime + CreationTime.dwHighDateTime
lngFileFlag = lngFileFlag + FileLen(strSrcPath & "\ " & strFilename)

lstSrc.AddItem strFileName
lstSrc.ItemData(lstSrc.NewIndex) = lngFileFlag

strFileName = Dir
Loop

'Get dest files
strFilename = Dir(strDstPath & "\*.* ")
Do Until strFilename = " "

hFile = CreateFile(strFilename, GENERIC_READ, _
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
Call GetFileTime (hFile, CreationTime, AccessTime As FILETIME, WriteTime)
CloseHandle hFile

lngFileFlag = CreationTime.dwLowDateTime + CreationTime.dwHighDateTime
lngFileFlag = lngFileFlag + FileLen(strSrcPath & "\ " & strFilename)

lstDst.AddItem strFileName
lstDst.ItemData(lstDst.NewIndex) = lngFileFlag

strFileName = Dir
Loop

For i = 0 To lstSrc.ListCount - 1
lngIndex = SendMessagebyString(lstSrc.hWnd, LB_FINDSTRINGEXACT, -1, lstSrc.List(i))
If lngIndex > = 0 Then
If lstDst.ItemData(lngIndex) <> lstSrc.ItemData(i) Then
Kill strDstPath & "\ " & lstDst.List(lngIndex)
FileCopy strSrcPath & "\ " & lstSrc.List(i), _
strDstPath & "\ " & lstDst.List(lngIndex)
End If
Else
FileCopy strSrcPath & "\ " & lstSrc.List(i), _
strDstPath & "\ " & lstDst.List(lngIndex)
End If
Next i
End Sub
[解决办法]
'Put 2 ListBox on your form, which named as lstSrc and lstDst

'API CreateFile 用来创建文件,目的是用文件句柄读取文件属性(创建日期等)
Declare Function CreateFile Lib "kernel32 " Alias "CreateFileA " (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

Public Const GENERIC_WRITE = &H40000000

Public Const FILE_SHARE_READ = &H1

Public Const OPEN_EXISTING = 3

Public Const FILE_ATTRIBUTE_NORMAL = &H80

'API GetFileTime 取文件时间,参数 hFile 用上一个 API 得到
Private Declare Function GetFileTime Lib "kernel32 " Alias "GetFileTime " (ByVal hFile As Long, lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As FILETIME) As Long

Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

'这个 API 用来查找 ListBox 中的列表项
Private Declare Function SendMessagebyString Lib _
"user32 " Alias "SendMessageA " (ByVal hWND As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lParam As String) As Long
Private Const LB_FINDSTRINGEXACT = &H1A2 '在 ListBox 中精确查找

'以下是更新过程,参数是源文件和目标文件路径
Private Sub Update_File(Byval strSrcPath As String, Byval strDstPath As String)
Dim strFilename As String
Dim CreationTime AS FILETIME, AccessTime AS FILETIME, WriteTime AS FILETIME
Dim lngFileFlag As Long, hFile As Long, i As Integer, lngIndex As Long

'Get source files
strFilename = Dir(strSrcPath & "\*.* ")
Do Until strFilename = " "
'取文件的时间属性
hFile = CreateFile(strFilename, GENERIC_READ, _
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
Call GetFileTime (hFile, CreationTime, AccessTime As FILETIME, WriteTime)


CloseHandle hFile

'将文件创建时间的高低双字相加(or 或运算更好,不会溢出)结果存入标志
lngFileFlag = CreationTime.dwLowDateTime Or CreationTime.dwHighDateTime
'标志再加上文件长度。只有时间和文件长度都相同,这个标志值才会相同。
lngFileFlag = lngFileFlag Or FileLen(strSrcPath & "\ " & strFilename)

lstSrc.AddItem strFileName '添加到列表
lstSrc.ItemData(lstSrc.NewIndex) = lngFileFlag '在列表项中保存标志值

strFileName = Dir
Loop

'Get dest files
'同样方法,在列表中保存目标文件名和标志值
strFilename = Dir(strDstPath & "\*.* ")
Do Until strFilename = " "

hFile = CreateFile(strFilename, GENERIC_READ, _
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
Call GetFileTime (hFile, CreationTime, AccessTime As FILETIME, WriteTime)
CloseHandle hFile

lngFileFlag = CreationTime.dwLowDateTime + CreationTime.dwHighDateTime
lngFileFlag = lngFileFlag + FileLen(strSrcPath & "\ " & strFilename)

lstDst.AddItem strFileName
lstDst.ItemData(lstDst.NewIndex) = lngFileFlag

strFileName = Dir
Loop

'以源文件为基准,查找目标文件
For i = 0 To lstSrc.ListCount - 1
lngIndex = SendMessagebyString(lstSrc.hWnd, LB_FINDSTRINGEXACT, -1, lstSrc.List(i))
If lngIndex > = 0 Then
'如果存在同名文件
If lstDst.ItemData(lngIndex) <> lstSrc.ItemData(i) Then '若标志值不同
Kill strDstPath & "\ " & lstDst.List(lngIndex) '删除旧目标文件
FileCopy strSrcPath & "\ " & lstSrc.List(i), _ '复制文件
strDstPath & "\ " & lstDst.List(lngIndex)
End If
Else '若无同名文件,直接复制
FileCopy strSrcPath & "\ " & lstSrc.List(i), _
strDstPath & "\ " & lstDst.List(lngIndex)
End If
Next i
End Sub

读书人网 >VB

热点推荐