我知道谈到实现FTP客户端功能时,
许多同仁立刻要用基于FTP协议上进行实现,
但这对于我们不是做产品而是做项目的同仁的来说,可能就没有给你有多阔余的时间来摆弄这个不算新技术的实现上的,而要一时要实现个功能齐全,BUG少而要达到一定效率的FTP客户端,也是很困难的。
呵呵,我也尝试过来实现它的几个基本功能,但用到项目中去,
确是BUG倍出,关键还是效率根本与市面上的工具不能同日而语(当然是我的差了呵)
最后,我也是没撤了,才想到用现在我要说的这种借鸡下蛋的方法
因为我们的项目是建立在Window系统上的,所以我的这种方法也只适合于window上的
系统提供的ftp.exe功能几乎齐全了,至少我们项目中用的功能都有了,我的方法就是利用系统的工具
结果测试表明,各方面都还不错。
还是代码来举例说明吧
Imports System
Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Net.Sockets
Public Class FTPTool
Private Const c_tmpFilePrefix As String = "ftpcmd"
Private Const c_tmpOutFilePrefix As String = "ftpresult"
Private Const c_ftpBatFilePrefix As String = "ftpbat"
Private Const c_txtEncodingName As String = "GB2312"
Private Const c_ftp_ls_cmd_nt As String = "ftp> ls -la"
Private Const c_ftp_ls_cmd_acos As String = "ftp> ls "
Private m_sRemoteHost As String
Private m_sRemotePath As String
Private m_sRemoteUser As String
Private m_sRemotePassword As String
Private m_sRemoteAcct As String
Private m_iRemotePort, m_iBytes As Int32
Private m_sMessageString As String
Private m_ftpBatFilePath As String = ""
Private m_ftpOutFilePath As String = ""
Private m_ftpBatCmdFilePath As String = ""
Private m_bUploading As Boolean = False
Private m_requestFile As String = ""
Public Sub New(ByVal sRemoteHost As String, _
ByVal sRemotePath As String, _
ByVal sRemoteUser As String, _
ByVal sRemotePassword As String, _
ByVal sRemoteAccount As String, _
ByVal iRemotePort As Int32)
m_sRemoteHost = sRemoteHost
m_sRemotePath = sRemotePath
m_sRemoteUser = sRemoteUser
m_sRemotePassword = sRemotePassword
m_sRemoteAcct = sRemoteAccount
m_sMessageString = ""
m_iRemotePort = 21
End Sub
''' <summary>
''' get file name list of ftp server which run at windowsNT.
''' if failed ,return nothing
''' </summary>
''' <returns>array of file name</returns>
''' <remarks></remarks>
Public Function GetFileListFromNT() As String()
Try
Me.MessageString = ""
'gen ftp command bat file
Dim cmdList As ArrayList = New ArrayList
cmdList.Add("open " & Me.m_sRemoteHost)
cmdList.Add("user " & Me.m_sRemoteUser & " " & Me.m_sRemotePassword)
cmdList.Add("binary")
cmdList.Add("cd " & Me.m_sRemotePath)
cmdList.Add("ls -la")
cmdList.Add("bye")
cmdList.Add("bye")
m_requestFile = "Window服务器:" & Me.m_sRemotePath
If CreateCmdBatFile(cmdList) = False Then
Return Nothing
End If
'call windows ftp client process(ftp.exe)
Dim list As ArrayList = ExecuteFtpClient()
If IsNothing(list) Then
Return Nothing
End If
'get file name from list
Dim revList() As String = GetFileNameList(list)
Return revList
Catch ex As Exception
Me.MessageString = ex.Message
Finally
'Clean tmpfile
CleanWorkTmpFile()
End Try
Return Nothing
End Function
Private Function CreateCmdBatFile(ByRef cmdList As ArrayList) As Boolean
m_ftpBatFilePath = ""
Dim ws As StreamWriter = Nothing
Dim fs As FileStream = Nothing
Try
'gen file name
m_ftpBatFilePath = c_tmpFilePrefix & System.DateTime.Now.Millisecond.ToString()
Do While File.Exists(Me.m_ftpBatFilePath)
m_ftpBatFilePath = c_tmpFilePrefix & System.DateTime.Now.Millisecond.ToString()
Loop
m_ftpBatFilePath = Path.GetDirectoryName(Application.ExecutablePath()) & "/" & m_ftpBatFilePath
'gen the file
fs = File.Open(m_ftpBatFilePath, FileMode.Append)
ws = New StreamWriter(fs, Encoding.GetEncoding(c_txtEncodingName))
'write command into the file
Dim i As Integer = 0
For i = 0 To cmdList.Count - 1
ws.WriteLine(cmdList(i).ToString())
Next
ws.Flush()
Return True
Catch ex As Exception
Throw ex
Finally
If Not IsNothing(ws) Then
ws.Close()
End If
ws = Nothing
If Not IsNothing(fs) Then
fs.Close()
End If
fs = Nothing
End Try
End Function
Private Function ExecuteFtpClient() As ArrayList
Dim reader As System.IO.StreamReader = Nothing
Try
'gen ftp process out file name
SetTempOutFileName()
CreateFtpCmdBatFile("ftp.exe -n -s:""" & Me.m_ftpBatFilePath & """ > " & m_ftpOutFilePath)
Dim procId As Integer = Shell(Me.m_ftpBatCmdFilePath, AppWinStyle.Hide)
Try
Dim obj As Process = Process.GetProcessById(procId)
If Not IsNothing(obj) Then
Do While Not obj.HasExited
System.Threading.Thread.Sleep(100)
Loop
End If
Catch
End Try
'get result infomation
Dim revList As ArrayList = GetResultList()
Return revList
Catch ex As Exception Throw ex
Finally
If Not IsNothing(reader) Then
reader.Close()
End If
End Try
End Function
Private Function GetResultList() As ArrayList
Dim lst As ArrayList = New ArrayList
If File.Exists(Me.m_ftpOutFilePath) Then
Dim fs As System.IO.FileStream = Nothing
Dim reader As System.IO.StreamReader = Nothing
Dim line As String = ""
Try
fs = New FileStream(Me.m_ftpOutFilePath, FileMode.Open)
reader = New System.IO.StreamReader(fs, Encoding.GetEncoding(c_txtEncodingName))
Dim tmp As String = Nothing
tmp = reader.ReadLine()
Do While Not IsNothing(tmp)
lst.Add(tmp)
tmp = reader.ReadLine()
Loop
Catch ex As Exception
Throw ex
Finally
If Not IsNothing(fs) Then
fs.Close()
End If
If Not IsNothing(reader) Then
reader.Close()
End If
End Try
Else
Throw New Exception(gf_GetMsg("100005"))
End If
Return lst
End Class
这里是一个FTP服务器是NT服务上FTP服务器,其他的FTP服务器登陆信息会有不同,这里就不在明细举例了。
方法都是类似