217 lines
7.2 KiB
C#
217 lines
7.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace AR.FTPClient
|
|
{
|
|
/// <summary>
|
|
/// ''' Represents a file or directory entry from an FTP listing
|
|
/// ''' </summary>
|
|
/// ''' <remarks>
|
|
/// ''' This class is used to parse the results from a detailed
|
|
/// ''' directory list from FTP. It supports most formats of
|
|
/// ''' </remarks>
|
|
public class FTPfileInfo
|
|
{
|
|
// Stores extended info about FTP file
|
|
|
|
public string FullName
|
|
{
|
|
get
|
|
{
|
|
var retval = Path + "/" + Filename;
|
|
return retval.Replace("//", "/");
|
|
}
|
|
}
|
|
public string Filename
|
|
{
|
|
get
|
|
{
|
|
return _filename;
|
|
}
|
|
}
|
|
public string Path
|
|
{
|
|
get
|
|
{
|
|
return _path;
|
|
}
|
|
}
|
|
public DirectoryEntryTypes FileType
|
|
{
|
|
get
|
|
{
|
|
return _fileType;
|
|
}
|
|
}
|
|
public long Size
|
|
{
|
|
get
|
|
{
|
|
return _size;
|
|
}
|
|
}
|
|
public DateTime FileDateTime
|
|
{
|
|
get
|
|
{
|
|
return _fileDateTime;
|
|
}
|
|
}
|
|
public string Permission
|
|
{
|
|
get
|
|
{
|
|
return _permission;
|
|
}
|
|
}
|
|
public string Extension
|
|
{
|
|
get
|
|
{
|
|
int i = this.Filename.LastIndexOf(".");
|
|
if (i >= 0 & i < (this.Filename.Length - 1))
|
|
return this.Filename.Substring(i + 1);
|
|
else
|
|
return "";
|
|
}
|
|
}
|
|
public string NameOnly
|
|
{
|
|
get
|
|
{
|
|
int i = this.Filename.LastIndexOf(".");
|
|
if (i > 0)
|
|
return this.Filename.Substring(0, i);
|
|
else
|
|
return this.Filename;
|
|
}
|
|
}
|
|
private string _filename;
|
|
private string _path;
|
|
private DirectoryEntryTypes _fileType;
|
|
private long _size;
|
|
private DateTime _fileDateTime;
|
|
private string _permission;
|
|
|
|
|
|
/// <summary>
|
|
/// ''' Identifies entry as either File or Directory
|
|
/// ''' </summary>
|
|
public enum DirectoryEntryTypes
|
|
{
|
|
File,
|
|
Directory,
|
|
Link
|
|
}
|
|
|
|
/// <summary>
|
|
/// ''' Constructor taking a directory listing line and path
|
|
/// ''' </summary>
|
|
/// ''' <param name="line">The line returned from the detailed directory list</param>
|
|
/// ''' <param name="path">Path of the directory</param>
|
|
/// ''' <remarks></remarks>
|
|
public FTPfileInfo(string line, string path)
|
|
{
|
|
// parse line
|
|
|
|
|
|
|
|
Match m = GetMatchingRegex(line);
|
|
if (m == null)
|
|
// failed
|
|
throw new ApplicationException("Unable to parse line: " + line);
|
|
else
|
|
{
|
|
_filename = m.Groups["name"].Value;
|
|
_path = path;
|
|
|
|
|
|
_permission = m.Groups["permission"].Value;
|
|
string _dir = m.Groups["dir"].Value;
|
|
if ((_dir != "" & (_dir == "d" || _dir == "D")))
|
|
{
|
|
_fileType = DirectoryEntryTypes.Directory;
|
|
_size = 0; // CLng(m.Groups("size").Value)
|
|
}
|
|
else if ((_dir != "" & (_dir == "l" || _dir == "L")))
|
|
{
|
|
_fileType = DirectoryEntryTypes.Link;
|
|
_size = 0; // CLng(m.Groups("size").Value)
|
|
}
|
|
else
|
|
{
|
|
_fileType = DirectoryEntryTypes.File;
|
|
_size = System.Convert.ToInt64(m.Groups["size"].Value);
|
|
}
|
|
|
|
|
|
try
|
|
{
|
|
var timestamp = m.Groups["timestamp"].Value;
|
|
if (timestamp.IndexOf(':') == -1)
|
|
{
|
|
_fileDateTime = DateTime.Parse(timestamp);
|
|
}
|
|
else
|
|
{
|
|
_fileDateTime = DateTime.Parse(DateTime.Now.Year + " " + timestamp);
|
|
}
|
|
|
|
}
|
|
catch
|
|
{
|
|
// MsgBox("datetime err=" & Now.Year & Space(1) & "value=" & m.Groups("timestamp").Value & vbCrLf & ex.Message.ToString)
|
|
_fileDateTime = DateTime.Parse("1982-11-23");
|
|
}
|
|
}
|
|
}
|
|
|
|
public FTPfileInfo(string filename, string permission, string dir, int size, DateTime filetime, Boolean isdir, string path)
|
|
{
|
|
_filename = filename;// m.Groups["name"].Value;
|
|
_path = path;
|
|
_permission = permission; // m.Groups["permission"].Value;
|
|
string _dir = dir;// m.Groups["dir"].Value;
|
|
if (isdir == true)
|
|
{
|
|
_fileType = DirectoryEntryTypes.Directory;
|
|
_size = 0; // CLng(m.Groups("size").Value)
|
|
}
|
|
else
|
|
{
|
|
_fileType = DirectoryEntryTypes.File;
|
|
_size = size;//
|
|
}
|
|
|
|
_fileDateTime = filetime;
|
|
}
|
|
|
|
private Match GetMatchingRegex(string line)
|
|
{
|
|
Regex rx;
|
|
Match m;
|
|
for (int i = 0; i <= _ParseFormats.Length - 1; i++)
|
|
{
|
|
rx = new Regex(_ParseFormats[i]);
|
|
m = rx.Match(line);
|
|
if (m.Success)
|
|
return m;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// ''' List of REGEX formats for different FTP server listing formats
|
|
/// ''' </summary>
|
|
/// ''' <remarks>
|
|
/// ''' The first three are various UNIX/LINUX formats, fourth is for MS FTP
|
|
/// ''' in detailed mode and the last for MS FTP in 'DOS' mode.
|
|
/// ''' I wish VB.NET had support for Const arrays like C# but there you go
|
|
/// ''' </remarks>
|
|
private static string[] _ParseFormats = new[] { @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<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>.+)", @"(?<dir>[\-dl])(?<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>.+)", @"(?<dir>[\-dl])(?<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>.+)", @"(?<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>.+)" };
|
|
}
|
|
}
|