Files
ATV_STDLabelAttach/Handler/Project/Class/FTP/FTPfileInfo.cs
2025-07-17 16:11:46 +09:00

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>.+)" };
}
}