基于vb环境WINDOWS API的ftp上传下载服务的实现.docx
《基于vb环境WINDOWS API的ftp上传下载服务的实现.docx》由会员分享,可在线阅读,更多相关《基于vb环境WINDOWS API的ftp上传下载服务的实现.docx(7页珍藏版)》请在冰豆网上搜索。
基于vb环境WINDOWSAPI的ftp上传下载服务的实现
基于vb的ftp上传下载服务的实现
OptionExplicit
PublicDeclareFunctionInternetOpenLib"wininet.dll"Alias"InternetOpenA"_
(ByValsAgentAsString,ByValLAccessTypeAsLong,ByValsProxyNameAsString,_
ByValSProxyBypassAsString,ByVallFlagsAsLong)AsLong
PublicDeclareFunctionInternetConnectLib"wininet.dll"Alias"InternetConnectA"_
(ByValhInternetSessionAsLong,ByValsServerNameAsString,_
ByValnServerPortAsInteger,ByValsUsernameAsString,_
ByValsPasswordAsString,ByVallServiceAsLong,_
ByVallFlagsAsLong,ByVallContextAsLong)AsLong
PublicDeclareFunctionFtpGetFileLib"wininet.dll"Alias"FtpGetFileA"_
(ByValhFtpSessionAsLong,ByVallpszRemoteFileAsString,_
ByVallpszNewFileAsString,ByValfFailIfExistsAsBoolean,_
ByValdwFlagsAndAttributesAsLong,ByValdwFlagsAsLong,_
ByValdwContextAsLong)AsBoolean
PublicDeclareFunctionFtpPutFileLib"wininet.dll"Alias"FtpPutFileA"_
(ByValhFtpSessionAsLong,ByVallpszLocalFileAsString,_
ByVallpszRemoteFileAsString,ByValdwFlagsAsLong,_
ByValdwContextAsLong)AsBoolean
PublicDeclareFunctionFtpDeleteFileLib"wininet.dll"Alias"FtpDeleteFileA"_
(ByValhFtpSessionAsLong,ByVallpszFileNameAsString)AsBoolean
PublicDeclareFunctionFtpRenameFileLib"wininet.dll"Alias"FtpRenameFileA"_
(ByValhFtpSessionAsLong,ByVallpszExsitingAsString,ByVallpszNewAsString)AsBoolean
PublicDeclareFunctionInternetCloseHandleLib"wininet.dll"(ByValhInetAsLong)AsInteger
PublicDeclareFunctionFtpFindFirstFileLib"wininet.dll"Alias"FtpFindFirstFileA"_
(ByValhFtpSessionAsLong,ByVallpszSearchFileAsString,_
lpFindFileDataAsWIN32_FIND_DATA,ByValdwFlagsAsLong,_
ByValdwContentAsLong)AsLong
PublicDeclareFunctionInternetFindNextFileLib"wininet.dll"Alias"InternetFindNextFileA"_
(ByValhFindAsLong,lpvFndDataAsWIN32_FIND_DATA)AsLong
PublicTypeFILETIME
dwLowDateTimeAsLong
dwHighDateTimeAsLong
EndType
PublicTypeWIN32_FIND_DATA
dwFilAttributesAsLong
ftCreationTimeAsFILETIME
ftLastAccessTimeAsFILETIME
ftLastWriteTimeAsFILETIME
nFileSizeHighAsLong
nFileSizeLowAsLong
dwReserved0AsLong
dwReserved1AsLong
cFileNameAsString*260
cAlternateAsString*14
EndType
PublicDeclareFunctionGetOpenFileNameLib"comdlg32.dll"Alias_
"GetOpenFileNameA"(pOpenfilenameAsOPENFILENAME)AsLong
TypeOPENFILENAME
lStructSizeAsLong
hwndOwnerAsLong
hInstanceAsLong
lpstrFilterAsString
lpstrCustomFilterAsString
nMaxCustFilterAsLong
nFilterIndexAsLong
lpstrFileAsString
nMaxFileAsLong
lpstrFileTitleAsString
nMaxFileTitleAsLong
lpstrInitialDirAsString
lpstrTitleAsString
flagsAsLong
nFileOffsetAsInteger
nFileExtensionAsInteger
lpstrDefExtAsString
lCustDataAsLong
lpfnHookAsLong
lpTemplateNameAsString
EndType
PrivateSubCommand1_Click()
lnginet=InternetOpen(vbNullString,INTERNET_OPEN_TYPE_PRECONFIG,_
vbNullString,vbNullString,0&)
IflnginetThen
lnginetconn=InternetConnect(lnginet,"ip地址",0,_
"用户名","密码",1,0,0)
IflnginetconnThen
blnRC=FtpGetFile(lnginetconn,"website/address.asp","c:
\address.asp",0,0,1,0)
IfblnRCThen
MsgBox"downloadok!
!
!
"
EndIf
InternetCloseHandlelnginetconn
InternetCloseHandlelnginet
MsgBox"closeok!
!
!
"
Else
MsgBox"can'tconnect"
EndIf
Else
MsgBox"ftpwrong"
EndIf
EndSub
PrivateSubCommand2_Click()
DimpDataAsWIN32_FIND_DATA
DimlngHINetAsLong
DimintErrorAsInteger
DimstrTempAsString
DimblnRCAsBoolean
pData.cFileName=String(260,0)
lnginet=InternetOpen(vbNullString,INTERNET_OPEN_TYPE_PRECONFIG,_
vbNullString,vbNullString,0&)
IflnginetThen
lnginetconn=InternetConnect(lnginet,"IP地址",0,_
"用户名","密码",1,0,0)
IflnginetconnThen
lngHINet=FtpFindFirstFile(lnginetconn,"*.*",pData,0,0)
strTemp=Left(pData.cFileName,InStr(1,pData.cFileName,String(1,0),vbBinaryCompare)-1)
Do
pData.cFileName=String(260,0)
blnRC=InternetFindNextFile(lngHINet,pData)
IfNotblnRCThen
ExitDo
Else
strTemp=Left(pData.cFileName,InStr(1,pData.cFileName,String(1,0),vbBinaryCompare)-1)
EndIf
Loop
Text1.Text=strTemp
EndIf
EndIf
InternetCloseHandlelngHINet
InternetCloseHandlelnginetconn
InternetCloseHandlelnginet
EndSub
在FTP中,Put、Rename、Delete是怎样的?
这些函数也相当简单。
首先来看看Put函数。
基本步骤是:
1、调用InternetOpen函数设置环境。
2、调用InternetConnect函数连接主机。
3、调用FtpPutFile函数得到文件。
4、用InternetCloseHandle函数关闭第1、2步的句柄。
当使用FtpGetFile时与上面的步骤看起来完全一样。
事实上唯一的区别是在第3步中调用了FtpPutFile。
VB特定调用这一函数的声明是:
PrivateDeclareFunctionFtpPutFileLib"wininet.dll"Alias"FtpPutFileA"_
(ByValhFtpSessionAsLong,ByVallpszLocalFileAsString,_
ByVallpszRemoteFileAsString,ByValdwFlagsAsLong,_
ByValdwContextAsLong)AsBoolean
第一个参数hFtpSession是InternetConnect调用返回的句柄值。
lpszNewFile和lpszRemoteFile分别是本地机上的文件名和将在远程主机上创建的文件名。
参数dwFlags指定为1时,用ASCII传输文件(A类传输方法),指定为2是用二进制传输文件(1类传输方法)。
由于DIRMAP.TXT是ASCII文本文件,我们传递值1。
最后,当使用回叫信号时,lContext用来识别应用程序前后关系。
因为在我们的例子中不使用回叫信号,所以这个值为0。
以下是得到DIRMAP.TXT文件并将其存在C:
\DIRMAP.TXT的调用。
blnRC=FtpPutFile(lngINetConn,揷:
\dirmap.txt?
揹irmap.txt?
1,0)
如果函数调用成功,blnRC为True,反之为False。
你可以看到,把文件放到FTP服务器上与从FTP服务器上得到文件一样简单。
有一点要注意,匿名用户无权在FTP服务器上创建文件。
所以要确定用来与FTP服务器连接的用户帐号要有创建文件的权限。
不然的话,FtpPutFile函数调用就会返回False,说明Put失败了。
现在我们用FtpDeleteFile函数删除一个名为Test.txt的文件。
同样只有第三步中的函数调用发生了改变。
VB特定调用这一函数的声明是:
PrivateDeclareFunctionFtpDeleteFileLib"wininet.dll"Alias"FtpDeleteFileA"_
(ByValhFtpSessionAsLong,ByVallpszFileNameAsString)AsBoolean
第一个参数hFtpSession是InternetConnect调用返回的句柄值。
lpszFileName是FTP服务器上要删除的文件。
下面是在FTP服务器上删除TEST.TXT文件的调用:
blnRC=FtpDeleteFile(lngINetConn,Test.txt)
如果函数调用成功,blnRC为True,反之为False。
要注意什么?
几乎所有的FTP函数都一样:
设置环境,连接主机,执行FTP任务,清除。
但是也有例外。
如何得到一个路径列表或者得到文件之前读文件的内容?
这些类型的FTP任务只是有一点点复杂。
首先看看路径列表问题。
列举路径的基本步骤也是一样的。
首先还是要设置环境,连接FTP服务器。
结束之后还是要清楚连接和句柄。
为了实际得到路径内容,需要使用两个新函数:
FtpFindFirstFile和InternetFindNextFile。
VB特定调用这一函数的声明是:
PrivateDeclareFunctionFtpFindFirstFileLib"wininet.dll"Alias"FtpFindFirstFileA"_
(ByValhFtpSessionAsLong,ByVallpszSearchFileAsString,_
lpFindFileDataAsWIN32_FIND_DATA,ByValdwFlagsAsLong,_
ByValdwContentAsLong)AsLong
第一个参数hFtpSession是InternetConnect调用返回的句柄值。
lpszSearchFile是FTP服务器上的路径或文件名。
如果你指定了一个空字符,就使用当前路径。
另外还可以指定通配符。
例如,要列出以ms开始的根目录下的路径内容,就使用ms*?
。
lpFindFileData与我们使用的其它参数有一点不同。
数据类型WIN32_FIND_DATA是用户定义类型,保存关于路径下的文件的信息。
类型看起来是这样的:
PrivateTypeWIN32_FIND_DATA
dwFileAttributesAsLong
ftCreationTimeAsFILETIME
ftLastAccessTimeAsFILETIME
ftLastWriteTimeAsFILETIME
nFileSizeHighAsLong
nFileSizeLowAsLong
dwReserved0AsLong
dwReserved1AsLong
cFileNameAsString*MAX_PATH
cAlternateAsString*14
EndType
注意,有许多参数有不同的用户定义数据类型:
FILETIME。
下面是它们的类型定义:
PrivateTypeFILETIME
dwLowDateTimeAsLong
dwHighDateTimeAsLong
EndType
在我们的例子中,只使用dwFileAttributes的内容,其中包含文件的属性,还有cFileName,其中包含文件名。
最后,我们的例子不使用dwFlags和dsContext,所以每个都传递0。
下面在当前路径下开始路径列举的调用:
lngHINet=FtpFindFirstFile(lngINetConn,"*.*",pData,0,0)
如果函数失败,就返回0。
否则,用来继续进行路径列举的lngHInet是一个有效句柄。
另外,第一个文件名和属性储存在pData参数中。
一旦调用了FtpFindFirstFile并返回一个有效句柄,我们要调用InternetFindNextFile函数除非它返回错误值18表示没有可以列举的文件。
对InternetFindNextFile的VB特定声明是:
PrivateDeclareFunctionInternetFindNextFileLib"wininet.dll"Alias"InternetFindNextFileA"_
(ByValhFindAsLong,lpvFindDataAsWIN32_FIND_DATA)AsLong
第一个参数,hFind是FtpFindFirstFile调用所返回的句柄。
lpvFindData是同样的用户定义类型,用在FtpFindFirstFile调用中存储文件信息。
下面是在路径中得到下一个文件的调用:
blnRC=InternetFindNextFile(lngHINet,pData)
如果调用成功,blnRC返回True,否则blnRC为False。
Err对象的LastDllError返回18表明再没有文件存在了。
现在再回来看看基本的四步:
第1步和第2步(设置环境和连接服务器)应该已经完成。
以下列出的第三步。
最后一步,第四步,就清除环境和连接句柄,跟前面一样:
DimpDataAsWIN32_FIND_DATA
DimlngHINetAsLong
DimintErrorAsInteger
DimstrTempAsString
DimblnRCAsBoolean
'initthefilenamebuffer
pData.cFileName=String(260,0)
'getthefirstfileinthedirectory...
lngHINet=FtpFindFirstFile(mlngINetConn,"*.*",pData,0,0)
'how'dwedo?
IflngHINet=0Then
'gettheerrorfromthefindfirstcall
intError=Err.LastDllError
'isthedirectoryempty?
IfintError<>ERROR_NO_MORE_FILESThen
'whoa...arealerror
‘Errorhandler?
EndIf
Else
'wegotsomedirinfo...
'getthename
strTemp=Left(pData.cFileName,InStr(1,pData.cFileName,String(1,0),vbBinaryCompare)-1)
Do
'initthefilenamebuffer
pData.cFileName=String(260,0)
'getthenextitem
blnRC=InternetFindNextFile(lngHINet,pData)
'how'dwedo?
IfNotblnRCThen
'gettheerrorfromthefindnextcall
intError=Err.LastDllError
'nomoreitems
IfintError<>18Then
'whoa...arealerror
卐rrorhandler?
ExitDo
Else
'nomoreitems...
ExitDo
EndIf
Else
'getthelastitemreturned
strTemp=Left(pData.cFileName,InStr(1,pData.cFileName,String(1,0),vbBinaryCompare)-1)
卻torethefileinfosomeplace?
EndIf
Loop
'closethehandleforthedirlisting
InternetCloseHandlelngHINet
EndIf