Advertisement
Guest User

Untitled

a guest
May 25th, 2016
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.64 KB | None | 0 0
  1.  
  2. Imports System.Collections.Generic
  3. Imports System.Net
  4. Imports System.IO
  5. Imports System.Text.RegularExpressions
  6.  
  7.  
  8. Namespace Utilities.FTP
  9.  
  10. #Region "FTP client class"
  11. ''' <summary>
  12. ''' A wrapper class for .NET 2.0 FTP
  13. ''' </summary>
  14. ''' <remarks>
  15. ''' This class does not hold open an FTP connection but
  16. ''' instead is stateless: for each FTP request it
  17. ''' connects, performs the request and disconnects.
  18. ''' </remarks>
  19. Public Class FTPclient
  20.  
  21. #Region "CONSTRUCTORS"
  22. ''' <summary>
  23. ''' Blank constructor
  24. ''' </summary>
  25. ''' <remarks>Hostname, username and password must be set manually</remarks>
  26. Sub New()
  27. End Sub
  28.  
  29. ''' <summary>
  30. ''' Constructor just taking the hostname
  31. ''' </summary>
  32. ''' <param name="Hostname">in either ftp://ftp.host.com or ftp.host.com form</param>
  33. ''' <remarks></remarks>
  34. Sub New(ByVal Hostname As String)
  35. _hostname = Hostname
  36. End Sub
  37.  
  38. ''' <summary>
  39. ''' Constructor taking hostname, username and password
  40. ''' </summary>
  41. ''' <param name="Hostname">in either ftp://ftp.host.com or ftp.host.com form</param>
  42. ''' <param name="Username">Leave blank to use 'anonymous' but set password to your email</param>
  43. ''' <param name="Password"></param>
  44. ''' <remarks></remarks>
  45. Sub New(ByVal Hostname As String, ByVal Username As String, ByVal Password As String)
  46. _hostname = Hostname
  47. _username = Username
  48. _password = Password
  49. End Sub
  50. #End Region
  51.  
  52. #Region "Directory functions"
  53. ''' <summary>
  54. ''' Return a simple directory listing
  55. ''' </summary>
  56. ''' <param name="directory">Directory to list, e.g. /pub</param>
  57. ''' <returns>A list of filenames and directories as a List(of String)</returns>
  58. ''' <remarks>For a detailed directory listing, use ListDirectoryDetail</remarks>
  59. Public Function ListDirectory(Optional ByVal directory As String = "") As List(Of String)
  60. 'return a simple list of filenames in directory
  61. Dim ftp As Net.FtpWebRequest = GetRequest(GetDirectory(directory))
  62. 'Set request to do simple list
  63. ftp.Method = Net.WebRequestMethods.Ftp.ListDirectory
  64.  
  65. Dim str As String = GetStringResponse(ftp)
  66. 'replace CRLF to CR, remove last instance
  67. str = str.Replace(vbCrLf, vbCr).TrimEnd(Chr(13))
  68. 'split the string into a list
  69. Dim result As New List(Of String)
  70. result.AddRange(str.Split(Chr(13)))
  71. Return result
  72. End Function
  73.  
  74. ''' <summary>
  75. ''' Return a detailed directory listing
  76. ''' </summary>
  77. ''' <param name="directory">Directory to list, e.g. /pub/etc</param>
  78. ''' <returns>An FTPDirectory object</returns>
  79. Public Function ListDirectoryDetail(Optional ByVal directory As String = "") As FTPdirectory
  80. Dim ftp As Net.FtpWebRequest = GetRequest(GetDirectory(directory))
  81. 'Set request to do simple list
  82. ftp.Method = Net.WebRequestMethods.Ftp.ListDirectoryDetails
  83.  
  84. Dim str As String = GetStringResponse(ftp)
  85. 'replace CRLF to CR, remove last instance
  86. str = str.Replace(vbCrLf, vbCr).TrimEnd(Chr(13))
  87. 'split the string into a list
  88. Return New FTPdirectory(str, _lastDirectory)
  89. End Function
  90.  
  91. #End Region
  92.  
  93. #Region "Upload: File transfer TO ftp server"
  94. ''' <summary>
  95. ''' Copy a local file to the FTP server
  96. ''' </summary>
  97. ''' <param name="localFilename">Full path of the local file</param>
  98. ''' <param name="targetFilename">Target filename, if required</param>
  99. ''' <returns></returns>
  100. ''' <remarks>If the target filename is blank, the source filename is used
  101. ''' (assumes current directory). Otherwise use a filename to specify a name
  102. ''' or a full path and filename if required.</remarks>
  103. Public Function Upload(ByVal localFilename As String, Optional ByVal targetFilename As String = "") As Boolean
  104. '1. check source
  105. If Not File.Exists(localFilename) Then
  106. Throw New ApplicationException("File " & localFilename & " not found")
  107. End If
  108. 'copy to FI
  109. Dim fi As New FileInfo(localFilename)
  110. Return Upload(fi, targetFilename)
  111. End Function
  112.  
  113. ''' <summary>
  114. ''' Upload a local file to the FTP server
  115. ''' </summary>
  116. ''' <param name="fi">Source file</param>
  117. ''' <param name="targetFilename">Target filename (optional)</param>
  118. ''' <returns></returns>
  119. Public Function Upload(ByVal fi As FileInfo, Optional ByVal targetFilename As String = "") As Boolean
  120. 'copy the file specified to target file: target file can be full path or just filename (uses current dir)
  121.  
  122. '1. check target
  123. Dim target As String
  124. If targetFilename.Trim = "" Then
  125. 'Blank target: use source filename & current dir
  126. target = Me.CurrentDirectory & fi.Name
  127. ElseIf targetFilename.Contains("/") Then
  128. 'If contains / treat as a full path
  129. target = AdjustDir(targetFilename)
  130. Else
  131. 'otherwise treat as filename only, use current directory
  132. target = CurrentDirectory & targetFilename
  133. End If
  134.  
  135. Dim URI As String = Hostname & target
  136. 'perform copy
  137. Dim ftp As Net.FtpWebRequest = GetRequest(URI)
  138.  
  139. 'Set request to upload a file in binary
  140. ftp.Method = Net.WebRequestMethods.Ftp.UploadFile
  141. ftp.UseBinary = True
  142.  
  143. 'Notify FTP of the expected size
  144. ftp.ContentLength = fi.Length
  145.  
  146. 'create byte array to store: ensure at least 1 byte!
  147. Const BufferSize As Integer = 2048
  148. Dim content(BufferSize - 1) As Byte, dataRead As Integer
  149.  
  150. 'open file for reading
  151. Using fs As FileStream = fi.OpenRead()
  152. Try
  153. 'open request to send
  154. Using rs As Stream = ftp.GetRequestStream
  155. Do
  156. dataRead = fs.Read(content, 0, BufferSize)
  157. rs.Write(content, 0, dataRead)
  158. Loop Until dataRead < BufferSize
  159. rs.Close()
  160. End Using
  161. Catch ex As Exception
  162.  
  163. Finally
  164. 'ensure file closed
  165. fs.Close()
  166. End Try
  167.  
  168. End Using
  169.  
  170. ftp = Nothing
  171. Return True
  172.  
  173. End Function
  174. #End Region
  175.  
  176. #Region "Download: File transfer FROM ftp server"
  177. ''' <summary>
  178. ''' Copy a file from FTP server to local
  179. ''' </summary>
  180. ''' <param name="sourceFilename">Target filename, if required</param>
  181. ''' <param name="localFilename">Full path of the local file</param>
  182. ''' <returns></returns>
  183. ''' <remarks>Target can be blank (use same filename), or just a filename
  184. ''' (assumes current directory) or a full path and filename</remarks>
  185. Public Function Download(ByVal sourceFilename As String, ByVal localFilename As String, Optional ByVal PermitOverwrite As Boolean = False) As Boolean
  186. '2. determine target file
  187. Dim fi As New FileInfo(localFilename)
  188. Return Me.Download(sourceFilename, fi, PermitOverwrite)
  189. End Function
  190.  
  191. 'Version taking an FtpFileInfo
  192. Public Function Download(ByVal file As FTPfileInfo, ByVal localFilename As String, Optional ByVal PermitOverwrite As Boolean = False) As Boolean
  193. Return Me.Download(file.FullName, localFilename, PermitOverwrite)
  194. End Function
  195.  
  196. 'Another version taking FtpFileInfo and FileInfo
  197. Public Function Download(ByVal file As FTPfileInfo, ByVal localFI As FileInfo, Optional ByVal PermitOverwrite As Boolean = False) As Boolean
  198. Return Me.Download(file.FullName, localFI, PermitOverwrite)
  199. End Function
  200.  
  201. 'Version taking string/FileInfo
  202. Public Function Download(ByVal sourceFilename As String, ByVal targetFI As FileInfo, Optional ByVal PermitOverwrite As Boolean = False) As Boolean
  203. '1. check target
  204. If targetFI.Exists And Not (PermitOverwrite) Then Throw New ApplicationException("Target file already exists")
  205.  
  206. '2. check source
  207. Dim target As String
  208. If sourceFilename.Trim = "" Then
  209. Throw New ApplicationException("File not specified")
  210. ElseIf sourceFilename.Contains("/") Then
  211. 'treat as a full path
  212. target = AdjustDir(sourceFilename)
  213. Else
  214. 'treat as filename only, use current directory
  215. target = CurrentDirectory & sourceFilename
  216. End If
  217.  
  218. Dim URI As String = Hostname & target
  219.  
  220. '3. perform copy
  221. Dim ftp As Net.FtpWebRequest = GetRequest(URI)
  222.  
  223. 'Set request to download a file in binary mode
  224. ftp.Method = Net.WebRequestMethods.Ftp.DownloadFile
  225. ftp.UseBinary = True
  226.  
  227. 'open request and get response stream
  228. Using response As FtpWebResponse = CType(ftp.GetResponse, FtpWebResponse)
  229. Using responseStream As Stream = response.GetResponseStream
  230. 'loop to read & write to file
  231. Using fs As FileStream = targetFI.OpenWrite
  232. Try
  233. Dim buffer(2047) As Byte
  234. Dim read As Integer = 0
  235. Do
  236. read = responseStream.Read(buffer, 0, buffer.Length)
  237. fs.Write(buffer, 0, read)
  238. Loop Until read = 0
  239. responseStream.Close()
  240. fs.Flush()
  241. fs.Close()
  242. Catch ex As Exception
  243. 'catch error and delete file only partially downloaded
  244. fs.Close()
  245. 'delete target file as it's incomplete
  246. targetFI.Delete()
  247. Throw
  248. End Try
  249. End Using
  250. responseStream.Close()
  251. End Using
  252. response.Close()
  253. End Using
  254.  
  255. Return True
  256. End Function
  257. #End Region
  258.  
  259. #Region "Other functions: Delete rename etc."
  260. ''' <summary>
  261. ''' Delete remote file
  262. ''' </summary>
  263. ''' <param name="filename">filename or full path</param>
  264. ''' <returns></returns>
  265. ''' <remarks></remarks>
  266. Public Function FtpDelete(ByVal filename As String) As Boolean
  267. 'Determine if file or full path
  268. Dim URI As String = Me.Hostname & GetFullPath(filename)
  269.  
  270. Dim ftp As Net.FtpWebRequest = GetRequest(URI)
  271. 'Set request to delete
  272. ftp.Method = Net.WebRequestMethods.Ftp.DeleteFile
  273. Try
  274. 'get response but ignore it
  275. Dim str As String = GetStringResponse(ftp)
  276. Catch ex As Exception
  277. Return False
  278. End Try
  279. Return True
  280. End Function
  281.  
  282. ''' <summary>
  283. ''' Determine if file exists on remote FTP site
  284. ''' </summary>
  285. ''' <param name="filename">Filename (for current dir) or full path</param>
  286. ''' <returns></returns>
  287. ''' <remarks>Note this only works for files</remarks>
  288. Public Function FtpFileExists(ByVal filename As String) As Boolean
  289. 'Try to obtain filesize: if we get error msg containing "550"
  290. 'the file does not exist
  291. Try
  292. Dim size As Long = GetFileSize(filename)
  293. Return True
  294.  
  295. Catch ex As Exception
  296. 'only handle expected not-found exception
  297. If TypeOf ex Is System.Net.WebException Then
  298. 'file does not exist/no rights error = 550
  299. If ex.Message.Contains("550") Then
  300. 'clear
  301. Return False
  302. Else
  303. Throw
  304. End If
  305. Else
  306. Throw
  307. End If
  308. End Try
  309. End Function
  310.  
  311. ''' <summary>
  312. ''' Determine size of remote file
  313. ''' </summary>
  314. ''' <param name="filename"></param>
  315. ''' <returns></returns>
  316. ''' <remarks>Throws an exception if file does not exist</remarks>
  317. Public Function GetFileSize(ByVal filename As String) As Long
  318. Dim path As String
  319. If filename.Contains("/") Then
  320. path = AdjustDir(filename)
  321. Else
  322. path = Me.CurrentDirectory & filename
  323. End If
  324. Dim URI As String = Me.Hostname & path
  325. Dim ftp As Net.FtpWebRequest = GetRequest(URI)
  326. 'Try to get info on file/dir?
  327. ftp.Method = Net.WebRequestMethods.Ftp.GetFileSize
  328. Dim tmp As String = Me.GetStringResponse(ftp)
  329. Return GetSize(ftp)
  330. End Function
  331.  
  332. Public Function FtpRename(ByVal sourceFilename As String, ByVal newName As String) As Boolean
  333. 'Does file exist?
  334. Dim source As String = GetFullPath(sourceFilename)
  335. If Not FtpFileExists(source) Then
  336. Throw New FileNotFoundException("File " & source & " not found")
  337. End If
  338.  
  339. 'build target name, ensure it does not exist
  340. Dim target As String = GetFullPath(newName)
  341. If target = source Then
  342. Throw New ApplicationException("Source and target are the same")
  343. ElseIf FtpFileExists(target) Then
  344. Throw New ApplicationException("Target file " & target & " already exists")
  345. End If
  346.  
  347. 'perform rename
  348. Dim URI As String = Me.Hostname & source
  349.  
  350. Dim ftp As Net.FtpWebRequest = GetRequest(URI)
  351. 'Set request to delete
  352. ftp.Method = Net.WebRequestMethods.Ftp.Rename
  353. ftp.RenameTo = target
  354. Try
  355. 'get response but ignore it
  356. Dim str As String = GetStringResponse(ftp)
  357. Catch ex As Exception
  358. Return False
  359. End Try
  360. Return True
  361. End Function
  362.  
  363. Public Function FtpCreateDirectory(ByVal dirpath As String) As Boolean
  364. 'perform create
  365. Dim URI As String = Me.Hostname & AdjustDir(dirpath)
  366. Dim ftp As Net.FtpWebRequest = GetRequest(URI)
  367. 'Set request to MkDir
  368. ftp.Method = Net.WebRequestMethods.Ftp.MakeDirectory
  369. Try
  370. 'get response but ignore it
  371. Dim str As String = GetStringResponse(ftp)
  372. Catch ex As Exception
  373. Return False
  374. End Try
  375. Return True
  376. End Function
  377.  
  378. Public Function FtpDeleteDirectory(ByVal dirpath As String) As Boolean
  379. 'perform remove
  380. Dim URI As String = Me.Hostname & AdjustDir(dirpath)
  381. Dim ftp As Net.FtpWebRequest = GetRequest(URI)
  382. 'Set request to RmDir
  383. ftp.Method = Net.WebRequestMethods.Ftp.RemoveDirectory
  384. Try
  385. 'get response but ignore it
  386. Dim str As String = GetStringResponse(ftp)
  387. Catch ex As Exception
  388. Return False
  389. End Try
  390. Return True
  391. End Function
  392. #End Region
  393.  
  394. #Region "private supporting fns"
  395. 'Get the basic FtpWebRequest object with the
  396. 'common settings and security
  397. Private Function GetRequest(ByVal URI As String) As FtpWebRequest
  398. 'create request
  399. Dim result As FtpWebRequest = CType(FtpWebRequest.Create(URI), FtpWebRequest)
  400. 'Set the login details
  401. result.Credentials = GetCredentials()
  402. 'Do not keep alive (stateless mode)
  403. result.KeepAlive = False
  404. Return result
  405. End Function
  406.  
  407.  
  408. ''' <summary>
  409. ''' Get the credentials from username/password
  410. ''' </summary>
  411. Private Function GetCredentials() As Net.ICredentials
  412. Return New Net.NetworkCredential(Username, Password)
  413. End Function
  414.  
  415. ''' <summary>
  416. ''' returns a full path using CurrentDirectory for a relative file reference
  417. ''' </summary>
  418. Private Function GetFullPath(ByVal file As String) As String
  419. If file.Contains("/") Then
  420. Return AdjustDir(file)
  421. Else
  422. Return Me.CurrentDirectory & file
  423. End If
  424. End Function
  425.  
  426. ''' <summary>
  427. ''' Amend an FTP path so that it always starts with /
  428. ''' </summary>
  429. ''' <param name="path">Path to adjust</param>
  430. ''' <returns></returns>
  431. ''' <remarks></remarks>
  432. Private Function AdjustDir(ByVal path As String) As String
  433. Return CStr(IIf(path.StartsWith("/"), "", "/")) & path
  434. End Function
  435.  
  436. Private Function GetDirectory(Optional ByVal directory As String = "") As String
  437. Dim URI As String
  438. If directory = "" Then
  439. 'build from current
  440. URI = Hostname & Me.CurrentDirectory
  441. _lastDirectory = Me.CurrentDirectory
  442. Else
  443. If Not directory.StartsWith("/") Then Throw New ApplicationException("Directory should start with /")
  444. URI = Me.Hostname & directory
  445. _lastDirectory = directory
  446. End If
  447. Return URI
  448. End Function
  449.  
  450. 'stores last retrieved/set directory
  451. Private _lastDirectory As String = ""
  452.  
  453. ''' <summary>
  454. ''' Obtains a response stream as a string
  455. ''' </summary>
  456. ''' <param name="ftp">current FTP request</param>
  457. ''' <returns>String containing response</returns>
  458. ''' <remarks>FTP servers typically return strings with CR and
  459. ''' not CRLF. Use respons.Replace(vbCR, vbCRLF) to convert
  460. ''' to an MSDOS string</remarks>
  461. Private Function GetStringResponse(ByVal ftp As FtpWebRequest) As String
  462. 'Get the result, streaming to a string
  463. Dim result As String = ""
  464. Using response As FtpWebResponse = CType(ftp.GetResponse, FtpWebResponse)
  465. Dim size As Long = response.ContentLength
  466. Using datastream As Stream = response.GetResponseStream
  467. Using sr As New StreamReader(datastream)
  468. result = sr.ReadToEnd()
  469. sr.Close()
  470. End Using
  471. datastream.Close()
  472. End Using
  473. response.Close()
  474. End Using
  475. Return result
  476. End Function
  477.  
  478. ''' <summary>
  479. ''' Gets the size of an FTP request
  480. ''' </summary>
  481. ''' <param name="ftp"></param>
  482. ''' <returns></returns>
  483. ''' <remarks></remarks>
  484. Private Function GetSize(ByVal ftp As FtpWebRequest) As Long
  485. Dim size As Long
  486. Using response As FtpWebResponse = CType(ftp.GetResponse, FtpWebResponse)
  487. size = response.ContentLength
  488. response.Close()
  489. End Using
  490. Return size
  491. End Function
  492. #End Region
  493.  
  494. #Region "Properties"
  495. Private _hostname As String
  496. ''' <summary>
  497. ''' Hostname
  498. ''' </summary>
  499. ''' <value></value>
  500. ''' <remarks>Hostname can be in either the full URL format
  501. ''' ftp://ftp.myhost.com or just ftp.myhost.com
  502. ''' </remarks>
  503. Public Property Hostname() As String
  504. Get
  505. If _hostname.StartsWith("ftp://") Then
  506. Return _hostname
  507. Else
  508. Return "ftp://" & _hostname
  509. End If
  510. End Get
  511. Set(ByVal value As String)
  512. _hostname = value
  513. End Set
  514. End Property
  515. Private _username As String
  516. ''' <summary>
  517. ''' Username property
  518. ''' </summary>
  519. ''' <value></value>
  520. ''' <remarks>Can be left blank, in which case 'anonymous' is returned</remarks>
  521. Public Property Username() As String
  522. Get
  523. Return IIf(_username = "", "anonymous", _username)
  524. End Get
  525. Set(ByVal value As String)
  526. _username = value
  527. End Set
  528. End Property
  529. Private _password As String
  530. Public Property Password() As String
  531. Get
  532. Return _password
  533. End Get
  534. Set(ByVal value As String)
  535. _password = value
  536. End Set
  537. End Property
  538.  
  539. ''' <summary>
  540. ''' The CurrentDirectory value
  541. ''' </summary>
  542. ''' <remarks>Defaults to the root '/'</remarks>
  543. Private _currentDirectory As String = "/"
  544. Public Property CurrentDirectory() As String
  545. Get
  546. 'return directory, ensure it ends with /
  547. Return _currentDirectory & CStr(IIf(_currentDirectory.EndsWith("/"), "", "/"))
  548. End Get
  549. Set(ByVal value As String)
  550. If Not value.StartsWith("/") Then Throw New ApplicationException("Directory should start with /")
  551. _currentDirectory = value
  552. End Set
  553. End Property
  554.  
  555.  
  556. #End Region
  557.  
  558. End Class
  559. #End Region
  560.  
  561. #Region "FTP file info class"
  562. ''' <summary>
  563. ''' Represents a file or directory entry from an FTP listing
  564. ''' </summary>
  565. ''' <remarks>
  566. ''' This class is used to parse the results from a detailed
  567. ''' directory list from FTP. It supports most formats of
  568. ''' </remarks>
  569. Public Class FTPfileInfo
  570. 'Stores extended info about FTP file
  571.  
  572. #Region "Properties"
  573. Public ReadOnly Property FullName() As String
  574. Get
  575. Return Path & Filename
  576. End Get
  577. End Property
  578. Public ReadOnly Property Filename() As String
  579. Get
  580. Return _filename
  581. End Get
  582. End Property
  583. Public ReadOnly Property Path() As String
  584. Get
  585. Return _path
  586. End Get
  587. End Property
  588. Public ReadOnly Property FileType() As DirectoryEntryTypes
  589. Get
  590. Return _fileType
  591. End Get
  592. End Property
  593. Public ReadOnly Property Size() As Long
  594. Get
  595. Return _size
  596. End Get
  597. End Property
  598. Public ReadOnly Property FileDateTime() As Date
  599. Get
  600. Return _fileDateTime
  601. End Get
  602. End Property
  603. Public ReadOnly Property Permission() As String
  604. Get
  605. Return _permission
  606. End Get
  607. End Property
  608. Public ReadOnly Property Extension() As String
  609. Get
  610. Dim i As Integer = Me.Filename.LastIndexOf(".")
  611. If i >= 0 And i < (Me.Filename.Length - 1) Then
  612. Return Me.Filename.Substring(i + 1)
  613. Else
  614. Return ""
  615. End If
  616. End Get
  617. End Property
  618. Public ReadOnly Property NameOnly() As String
  619. Get
  620. Dim i As Integer = Me.Filename.LastIndexOf(".")
  621. If i > 0 Then
  622. Return Me.Filename.Substring(0, i)
  623. Else
  624. Return Me.Filename
  625. End If
  626. End Get
  627. End Property
  628. Private _filename As String
  629. Private _path As String
  630. Private _fileType As DirectoryEntryTypes
  631. Private _size As Long
  632. Private _fileDateTime As Date
  633. Private _permission As String
  634.  
  635. #End Region
  636.  
  637. ''' <summary>
  638. ''' Identifies entry as either File or Directory
  639. ''' </summary>
  640. Public Enum DirectoryEntryTypes
  641. File
  642. Directory
  643. End Enum
  644.  
  645. ''' <summary>
  646. ''' Constructor taking a directory listing line and path
  647. ''' </summary>
  648. ''' <param name="line">The line returned from the detailed directory list</param>
  649. ''' <param name="path">Path of the directory</param>
  650. ''' <remarks></remarks>
  651. Sub New(ByVal line As String, ByVal path As String)
  652. 'parse line
  653. Dim m As Match = GetMatchingRegex(line)
  654. If m Is Nothing Then
  655. 'failed
  656. Throw New ApplicationException("Unable to parse line: " & line)
  657. Else
  658. _filename = m.Groups("name").Value
  659. _path = path
  660. _size = CLng(m.Groups("size").Value)
  661. _permission = m.Groups("permission").Value
  662. Dim _dir As String = m.Groups("dir").Value
  663. If (_dir <> "" And _dir <> "-") Then
  664. _fileType = DirectoryEntryTypes.Directory
  665. Else
  666. _fileType = DirectoryEntryTypes.File
  667. End If
  668.  
  669. Try
  670. _fileDateTime = Date.Parse(m.Groups("timestamp").Value)
  671. Catch ex As Exception
  672. _fileDateTime = Nothing
  673. End Try
  674.  
  675. End If
  676. End Sub
  677.  
  678. Private Function GetMatchingRegex(ByVal line As String) As Match
  679. Dim rx As Regex, m As Match
  680. For i As Integer = 0 To _ParseFormats.Length - 1
  681. rx = New Regex(_ParseFormats(i))
  682. m = rx.Match(line)
  683. If m.Success Then Return m
  684. Next
  685. Return Nothing
  686. End Function
  687.  
  688. #Region "Regular expressions for parsing LIST results"
  689. ''' <summary>
  690. ''' List of REGEX formats for different FTP server listing formats
  691. ''' </summary>
  692. ''' <remarks>
  693. ''' The first three are various UNIX/LINUX formats, fourth is for MS FTP
  694. ''' in detailed mode and the last for MS FTP in 'DOS' mode.
  695. ''' I wish VB.NET had support for Const arrays like C# but there you go
  696. ''' </remarks>
  697. Private Shared _ParseFormats As String() = { _
  698. "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", _
  699. "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", _
  700. "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)", _
  701. "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)", _
  702. "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(\s+)(?<size>(\d+))(\s+)(?<ctbit>(\w+\s\w+))(\s+)(?<size2>(\d+))\s+(?<timestamp>\w+\s+\d+\s+\d{2}:\d{2})\s+(?<name>.+)", _
  703. "(?<timestamp>\d{2}\-\d{2}\-\d{2}\s+\d{2}:\d{2}[Aa|Pp][mM])\s+(?<dir>\<\w+\>){0,1}(?<size>\d+){0,1}\s+(?<name>.+)"}
  704. #End Region
  705. End Class
  706. #End Region
  707.  
  708. #Region "FTP Directory class"
  709. ''' <summary>
  710. ''' Stores a list of files and directories from an FTP result
  711. ''' </summary>
  712. ''' <remarks></remarks>
  713. Public Class FTPdirectory
  714. Inherits List(Of FTPfileInfo)
  715.  
  716. Sub New()
  717. 'creates a blank directory listing
  718. End Sub
  719.  
  720. ''' <summary>
  721. ''' Constructor: create list from a (detailed) directory string
  722. ''' </summary>
  723. ''' <param name="dir">directory listing string</param>
  724. ''' <param name="path"></param>
  725. ''' <remarks></remarks>
  726. Sub New(ByVal dir As String, ByVal path As String)
  727. For Each line As String In dir.Replace(vbLf, "").Split(CChar(vbCr))
  728. 'parse
  729. If line <> "" Then Me.Add(New FTPfileInfo(line, path))
  730. Next
  731. End Sub
  732.  
  733. ''' <summary>
  734. ''' Filter out only files from directory listing
  735. ''' </summary>
  736. ''' <param name="ext">optional file extension filter</param>
  737. ''' <returns>FTPdirectory listing</returns>
  738. Public Function GetFiles(Optional ByVal ext As String = "") As FTPdirectory
  739. Return Me.GetFileOrDir(FTPfileInfo.DirectoryEntryTypes.File, ext)
  740. End Function
  741.  
  742. ''' <summary>
  743. ''' Returns a list of only subdirectories
  744. ''' </summary>
  745. ''' <returns>FTPDirectory list</returns>
  746. ''' <remarks></remarks>
  747. Public Function GetDirectories() As FTPdirectory
  748. Return Me.GetFileOrDir(FTPfileInfo.DirectoryEntryTypes.Directory)
  749. End Function
  750.  
  751. 'internal: share use function for GetDirectories/Files
  752. Private Function GetFileOrDir(ByVal type As FTPfileInfo.DirectoryEntryTypes, Optional ByVal ext As String = "") As FTPdirectory
  753. Dim result As New FTPdirectory()
  754. For Each fi As FTPfileInfo In Me
  755. If fi.FileType = type Then
  756. If ext = "" Then
  757. result.Add(fi)
  758. ElseIf ext = fi.Extension Then
  759. result.Add(fi)
  760. End If
  761. End If
  762. Next
  763. Return result
  764.  
  765. End Function
  766.  
  767. Public Function FileExists(ByVal filename As String) As Boolean
  768. For Each ftpfile As FTPfileInfo In Me
  769. If ftpfile.Filename = filename Then
  770. Return True
  771. End If
  772. Next
  773. Return False
  774. End Function
  775.  
  776. Private Const slash As Char = "/"
  777.  
  778. Public Shared Function GetParentDirectory(ByVal dir As String) As String
  779. Dim tmp As String = dir.TrimEnd(slash)
  780. Dim i As Integer = tmp.LastIndexOf(slash)
  781. If i > 0 Then
  782. Return tmp.Substring(0, i - 1)
  783. Else
  784. Throw New ApplicationException("No parent for root")
  785. End If
  786. End Function
  787. End Class
  788. #End Region
  789.  
  790. End Namespace
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement