//******************************************************************************************************
// FilePath.cs - Gbtc
//
// Copyright © 2012, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://www.opensource.org/licenses/eclipse-1.0.php
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 02/05/2003 - J. Ritchie Carroll
// Generated original version of source code.
// 12/29/2005 - Pinal C. Patel
// Migrated 2.0 version of source code from 1.1 source (GSF.Shared.FilePath).
// 08/22/2007 - Darrell Zuercher
// Edited code comments.
// 09/19/2008 - J. Ritchie Carroll
// Converted to C#.
// 10/24/2008 - Pinal C. Patel
// Edited code comments.
// 12/17/2008 - F. Russell Robertson
// Fixed bug in GetFilePatternRegularExpression().
// 06/30/2009 - Pinal C. Patel
// Removed FilePathHasFileName() since the result was error prone.
// 09/14/2009 - Stephen C. Wills
// Added new header and license agreement.
// 09/17/2009 - Pinal C. Patel
// Modified GetAbsolutePath() to remove dependency on HttpContext.Current.
// 04/19/2010 - Pinal C. Patel
// Added GetApplicationDataFolder() method.
// 04/21/2010 - Pinal C. Patel
// Updated GetApplicationDataFolder() to include the company name if available.
// 01/28/2011 - J. Ritchie Carroll
// Added IsValidFileName function.
// 02/14/2011 - J. Ritchie Carroll
// Fixed bug in GetDirectoryName where last directory was being truncated as a file name.
// 06/06/2011 - Stephen C. Wills
// Fixed bug in GetFileName where path suffix was being removed before extracting the file name.
// 07/29/2011 - Pinal C. Patel
// Updated GetApplicationDataFolder() to use the TEMP directory for web applications.
// 12/14/2012 - Starlynn Danyelle Gilliam
// Modified Header.
//
//******************************************************************************************************
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web.Hosting;
using GSF.Identity;
using GSF.Interop;
using GSF.Reflection;
namespace GSF.IO
{
/// <summary>
/// Contains File and Path manipulation methods.
/// </summary>
public static class FilePath
{
#region [ Members ]
// Nested Types
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct NETRESOURCE
{
public readonly int dwScope;
public int dwType;
public readonly int dwDisplayType;
public readonly int dwUsage;
public readonly string lpLocalName;
public string lpRemoteName;
public readonly string lpComment;
public readonly string lpProvider;
}
// Constants
private const int RESOURCETYPE_DISK = 0x1;
// Delegates
[DllImport("mpr.dll", EntryPoint = "WNetAddConnection2W", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int WNetAddConnection2(ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags);
[DllImport("mpr.dll", EntryPoint = "WNetCancelConnection2W", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int WNetCancelConnection2(string lpName, int dwFlags, [MarshalAs(UnmanagedType.Bool)] bool fForce);
// Fields
private static readonly string s_fileNameCharPattern;
#endregion
#region [ Constructor ]
static FilePath()
{
StringBuilder pattern = new StringBuilder();
// Defines a regular expression pattern for a valid file name character. We do this by
// allowing any characters except those that would not be valid as part of a filename.
// This essentially builds the "?" wildcard pattern match.
pattern.Append("[^");
pattern.Append(Path.DirectorySeparatorChar.RegexEncode());
pattern.Append(Path.AltDirectorySeparatorChar.RegexEncode());
pattern.Append(Path.PathSeparator.RegexEncode());
pattern.Append(Path.VolumeSeparatorChar.RegexEncode());
foreach (char c in Path.GetInvalidPathChars())
{
pattern.Append(c.RegexEncode());
}
pattern.Append("]");
s_fileNameCharPattern = pattern.ToString();
}
#endregion
#region [ Methods ]
#if !MONO
/// <summary>
/// Connects to a network share with the specified user's credentials.
/// </summary>
/// <param name="sharename">UNC share name to connect to.</param>
/// <param name="username">Username to use for connection.</param>
/// <param name="password">Password to use for connection.</param>
/// <param name="domain">Domain name to use for connetion. Specify the computer name for local system accounts.</param>
public static void ConnectToNetworkShare(string sharename, string username, string password, string domain)
{
NETRESOURCE resource = new NETRESOURCE();
int result;
resource.dwType = RESOURCETYPE_DISK;
resource.lpRemoteName = sharename;
if (domain.Length > 0)
username = domain + "\\" + username;
result = WNetAddConnection2(ref resource, password, username, 0);
if (result != 0)
throw new InvalidOperationException("Failed to connect to network share \"" + sharename + "\" as user " + username + " - " + WindowsApi.GetErrorMessage(result));
}
/// <summary>
/// Disconnects the specified network share.
/// </summary>
/// <param name="sharename">UNC share name to disconnect from.</param>
public static void DisconnectFromNetworkShare(string sharename)
{
DisconnectFromNetworkShare(sharename, true);
}
/// <summary>
/// Disconnects the specified network share.
/// </summary>
/// <param name="sharename">UNC share name to disconnect from.</param>
/// <param name="force"><c>true</c> to force a disconnect; otherwise <c>false</c>.</param>
public static void DisconnectFromNetworkShare(string sharename, bool force)
{
int result = WNetCancelConnection2(sharename, 0, force);
if (result != 0)
throw new InvalidOperationException("Failed to disconnect from network share \"" + sharename + "\" - " + WindowsApi.GetErrorMessage(result));
}
#endif
/// <summary>
/// Determines whether the specified file name matches any of the given file specs (wildcards are defined as '*' or '?' characters).
/// </summary>
/// <param name="fileSpecs">The file specs used for matching the specified file name.</param>
/// <param name="fileName">The file name to be tested against the specified file specs for a match.</param>
/// <param name="ignoreCase"><c>true</c> to specify a case-insensitive match; otherwise <c>false</c>.</param>
/// <returns><c>true</c> if the specified file name matches any of the given file specs; otherwise <c>false</c>.</returns>
public static bool IsFilePatternMatch(string[] fileSpecs, string fileName, bool ignoreCase)
{
bool found = false;
foreach (string fileSpec in fileSpecs)
{
if (IsFilePatternMatch(fileSpec, fileName, ignoreCase))
{
found = true;
break;
}
}
return found;
}
/// <summary>
/// Determines whether the specified file name matches the given file spec (wildcards are defined as '*' or '?' characters).
/// </summary>
/// <param name="fileSpec">The file spec used for matching the specified file name.</param>
/// <param name="fileName">The file name to be tested against the specified file spec for a match.</param>
/// <param name="ignoreCase"><c>true</c> to specify a case-insensitive match; otherwise <c>false</c>.</param>
/// <returns><c>true</c> if the specified file name matches the given file spec; otherwise <c>false</c>.</returns>
public static bool IsFilePatternMatch(string fileSpec, string fileName, bool ignoreCase)
{
return (new Regex(GetFilePatternRegularExpression(fileSpec), (ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None))).IsMatch(fileName);
}
/// <summary>
/// Determines if the specified file name and path is valid.
/// </summary>
/// <param name="filePath">The file name with optional path to test for validity.</param>
/// <returns><c>true</c> if the specified <paramref name="filePath"/> is a valid name; otherwise <c>false</c>.</returns>
public static bool IsValidFileName(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
return false;
try
{
// Attempt to parse directory and file name - this will catch most issues
string directory = Path.GetDirectoryName(filePath);
string filename = Path.GetFileName(filePath);
// Check for invalid directory characters
if (!string.IsNullOrWhiteSpace(directory) && directory.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
return false;
// Check for invalid file name characters
if (string.IsNullOrWhiteSpace(filename) || filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
return false;
// Recurse in to check validity of each directory name
if (!string.IsNullOrWhiteSpace(directory) && !string.IsNullOrWhiteSpace(Path.GetFileName(directory)))
return IsValidFileName(directory);
}
catch
{
// If you can't parse a file name or directory, file path is definitely not valid
return false;
}
return true;
}
/// <summary>
/// Gets the file name and extension from the specified file path.
/// </summary>
/// <param name="filePath">The file path from which the file name and extension is to be obtained.</param>
/// <returns>File name and extension if the file path has it; otherwise empty string.</returns>
public static string GetFileName(string filePath)
{
return Path.GetFileName(filePath);
}
/// <summary>
/// Gets the extension from the specified file path.
/// </summary>
/// <param name="filePath">The file path from which the extension is to be obtained.</param>
/// <returns>File extension.</returns>
public static string GetExtension(string filePath)
{
return Path.GetExtension(RemovePathSuffix(filePath));
}
/// <summary>
/// Gets the file name without extension from the specified file path.
/// </summary>
/// <param name="filePath">The file path from which the file name is to be obtained.</param>
/// <returns>File name without the extension if the file path has it; otherwise empty string.</returns>
public static string GetFileNameWithoutExtension(string filePath)
{
return Path.GetFileNameWithoutExtension(RemovePathSuffix(filePath));
}
/// <summary>
/// Gets the size of the specified file.
/// </summary>
/// <param name="fileName">Name of file whose size is to be retrieved.</param>
/// <returns>The size of the specified file.</returns>
public static long GetFileLength(string fileName)
{
try
{
return (new FileInfo(fileName)).Length;
}
catch
{
return -1;
}
}
/// <summary>
/// Gets a list of files under the specified path. Search wildcard pattern (c:\Data\*.dat) can be used for
/// including only the files matching the pattern or path wildcard pattern (c:\Data\*\*.dat) to indicate the
/// inclusion of files under all subdirectories in the list.
/// </summary>
/// <param name="path">The path for which a list of files is to be returned.</param>
/// <returns>A list of files under the given path.</returns>
public static string[] GetFileList(string path)
{
string directory = GetDirectoryName(path);
string filePattern = GetFileName(path);
SearchOption options = SearchOption.TopDirectoryOnly;
if (string.IsNullOrEmpty(filePattern))
{
// No wildcard pattern was specified, so get a listing of all files.
filePattern = "*.*";
}
if (GetLastDirectoryName(directory) == "*")
{
// Path wildcard pattern is used to specify the option to include subdirectories.
options = SearchOption.AllDirectories;
directory = directory.Remove(directory.LastIndexOf("*"));
}
return Directory.GetFiles(directory, filePattern, options);
}
/// <summary>
/// Gets a regular expression pattern that simulates wildcard matching for filenames (wildcards are defined as '*' or '?' characters).
/// </summary>
/// <param name="fileSpec">The file spec for which the regular expression pattern if to be generated.</param>
/// <returns>Regular expression pattern that simulates wildcard matching for filenames.</returns>
public static string GetFilePatternRegularExpression(string fileSpec)
{
// Replaces wildcard file patterns with their equivalent regular expression.
fileSpec = fileSpec.Replace("\\", "\\u005C"); // Backslash in Regex means special sequence. Here, we really want a backslash.
fileSpec = fileSpec.Replace(".", "\\u002E"); // Dot in Regex means any character. Here, we really want a dot.
fileSpec = fileSpec.Replace("?", s_fileNameCharPattern);
fileSpec = fileSpec.Replace("*", "(" + s_fileNameCharPattern + ")*");
return "^" + fileSpec + "$";
}
/// <summary>
/// Gets the directory information from the specified file path.
/// </summary>
/// <param name="filePath">The file path from which the directory information is to be obtained.</param>
/// <returns>Directory information.</returns>
public static string GetDirectoryName(string filePath)
{
return AddPathSuffix(Path.GetDirectoryName(filePath));
}
/// <summary>
/// Gets the last directory name from a file path.
/// </summary>
/// <param name="filePath">The file path from where the last directory name is to be retrieved.</param>
/// <returns>The last directory name from a file path.</returns>
/// <remarks>
/// <see cref="GetLastDirectoryName(string)"/> would return sub2 from c:\windows\sub2\filename.ext.
/// </remarks>
public static string GetLastDirectoryName(string filePath)
{
// Test case should verify the following:
// FilePath.GetLastDirectoryName(@"C:\Test\sub") == "Test" <-- sub assumed to be filename
// FilePath.GetLastDirectoryName(@"C:\Test\sub\") == "sub" <-- sub assumed to be directory
if (!string.IsNullOrEmpty(filePath))
{
int index;
char[] dirVolChars = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, Path.VolumeSeparatorChar };
// Remove file name and trailing directory seperator character from the file path.
filePath = RemovePathSuffix(GetDirectoryName(filePath));
// Keep going through the file path until all directory seperator characters are removed.
while ((index = filePath.IndexOfAny(dirVolChars)) > -1)
{
filePath = filePath.Substring(index + 1);
}
return filePath;
}
else
{
throw new ArgumentNullException("filePath");
}
}
/// <summary>
/// Gets the absolute file path for the specified file name or relative file path.
/// </summary>
/// <param name="filePath">File name or relative file path.</param>
/// <returns>Absolute file path for the specified file name or relative file path.</returns>
public static string GetAbsolutePath(string filePath)
{
if (!Path.IsPathRooted(filePath))
{
// The specified path is a relative one since it is not rooted.
switch (Common.GetApplicationType())
{
// Prepends the application's root to the file path.
case ApplicationType.Web:
filePath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, filePath);
break;
case ApplicationType.WindowsCui:
case ApplicationType.WindowsGui:
filePath = Path.Combine(GetDirectoryName(AssemblyInfo.EntryAssembly.Location), filePath);
break;
}
}
return RemovePathSuffix(filePath);
}
/// <summary>
/// Determines if the specified <paramref name="filePath"/> is contained with the current executable path.
/// </summary>
/// <param name="filePath">File name or relative file path.</param>
/// <returns><c>true</c> if the specified <paramref name="filePath"/> is contained with the current executable path; otherwise <c>false</c>.</returns>
public static bool InApplicationPath(string filePath)
{
return GetAbsolutePath(filePath).StartsWith(GetAbsolutePath(""), StringComparison.InvariantCultureIgnoreCase);
}
/// <summary>
/// Gets the path to the folder where data related to the current application can be stored.
/// </summary>
/// <returns>Path to the folder where data related to the current application can be stored.</returns>
public static string GetApplicationDataFolder()
{
string rootFolder;
ApplicationType platform = Common.GetApplicationType();
if (platform == ApplicationType.Web)
{
// Treat web application special.
if (HostingEnvironment.ApplicationVirtualPath == "/")
rootFolder = Path.Combine(Path.GetTempPath(), HostingEnvironment.SiteName);
else
rootFolder = Path.Combine(Path.GetTempPath(), HostingEnvironment.ApplicationVirtualPath.Trim('/'));
// Create a user folder if ID is available.
string userID = UserInfo.RemoteUserID;
if (string.IsNullOrEmpty(userID))
{
// ID is not available.
return rootFolder;
}
else
{
// Remove domain from ID.
if (!userID.Contains("\\"))
return Path.Combine(rootFolder, userID);
else
return Path.Combine(rootFolder, userID.Remove(0, userID.IndexOf('\\') + 1));
}
}
else
{
// Use entry assembly for everything else.
rootFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
if (string.IsNullOrEmpty(AssemblyInfo.EntryAssembly.Company))
return Path.Combine(rootFolder, AssemblyInfo.EntryAssembly.Name);
else
return Path.Combine(rootFolder, AssemblyInfo.EntryAssembly.Company + "\\" + AssemblyInfo.EntryAssembly.Name);
}
}
/// <summary>
/// Makes sure path is suffixed with standard <see cref="Path.DirectorySeparatorChar"/>.
/// </summary>
/// <param name="filePath">The file path to be suffixed.</param>
/// <returns>Suffixed path.</returns>
public static string AddPathSuffix(string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
filePath = Path.DirectorySeparatorChar.ToString();
}
else
{
char suffixChar = filePath[filePath.Length - 1];
if (suffixChar != Path.DirectorySeparatorChar && suffixChar != Path.AltDirectorySeparatorChar)
filePath += Path.DirectorySeparatorChar;
}
return filePath;
}
/// <summary>
/// Makes sure path is not suffixed with <see cref="Path.DirectorySeparatorChar"/> or <see cref="Path.AltDirectorySeparatorChar"/>.
/// </summary>
/// <param name="filePath">The file path to be unsuffixed.</param>
/// <returns>Unsuffixed path.</returns>
public static string RemovePathSuffix(string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
filePath = "";
Lines 1–500 of 904. Load more
//****************************************************************************************************** // FilePath.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/eclipse-1.0.php // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 02/05/2003 - J. Ritchie Carroll // Generated original version of source code. // 12/29/2005 - Pinal C. Patel // Migrated 2.0 version of source code from 1.1 source (GSF.Shared.FilePath). // 08/22/2007 - Darrell Zuercher // Edited code comments. // 09/19/2008 - J. Ritchie Carroll // Converted to C#. // 10/24/2008 - Pinal C. Patel // Edited code comments. // 12/17/2008 - F. Russell Robertson // Fixed bug in GetFilePatternRegularExpression(). // 06/30/2009 - Pinal C. Patel // Removed FilePathHasFileName() since the result was error prone. // 09/14/2009 - Stephen C. Wills // Added new header and license agreement. // 09/17/2009 - Pinal C. Patel // Modified GetAbsolutePath() to remove dependency on HttpContext.Current. // 04/19/2010 - Pinal C. Patel // Added GetApplicationDataFolder() method. // 04/21/2010 - Pinal C. Patel // Updated GetApplicationDataFolder() to include the company name if available. // 01/28/2011 - J. Ritchie Carroll // Added IsValidFileName function. // 02/14/2011 - J. Ritchie Carroll // Fixed bug in GetDirectoryName where last directory was being truncated as a file name. // 06/06/2011 - Stephen C. Wills // Fixed bug in GetFileName where path suffix was being removed before extracting the file name. // 07/29/2011 - Pinal C. Patel // Updated GetApplicationDataFolder() to use the TEMP directory for web applications. // 12/14/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Web.Hosting; using GSF.Identity; using GSF.Interop; using GSF.Reflection; namespace GSF.IO { /// <summary> /// Contains File and Path manipulation methods. /// </summary> public static class FilePath { #region [ Members ] // Nested Types [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct NETRESOURCE { public readonly int dwScope; public int dwType; public readonly int dwDisplayType; public readonly int dwUsage; public readonly string lpLocalName; public string lpRemoteName; public readonly string lpComment; public readonly string lpProvider; } // Constants private const int RESOURCETYPE_DISK = 0x1; // Delegates [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2W", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)] private static extern int WNetAddConnection2(ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags); [DllImport("mpr.dll", EntryPoint = "WNetCancelConnection2W", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)] private static extern int WNetCancelConnection2(string lpName, int dwFlags, [MarshalAs(UnmanagedType.Bool)] bool fForce); // Fields private static readonly string s_fileNameCharPattern; #endregion #region [ Constructor ] static FilePath() { StringBuilder pattern = new StringBuilder(); // Defines a regular expression pattern for a valid file name character. We do this by // allowing any characters except those that would not be valid as part of a filename. // This essentially builds the "?" wildcard pattern match. pattern.Append("[^"); pattern.Append(Path.DirectorySeparatorChar.RegexEncode()); pattern.Append(Path.AltDirectorySeparatorChar.RegexEncode()); pattern.Append(Path.PathSeparator.RegexEncode()); pattern.Append(Path.VolumeSeparatorChar.RegexEncode()); foreach (char c in Path.GetInvalidPathChars()) { pattern.Append(c.RegexEncode()); } pattern.Append("]"); s_fileNameCharPattern = pattern.ToString(); } #endregion #region [ Methods ] #if !MONO /// <summary> /// Connects to a network share with the specified user's credentials. /// </summary> /// <param name="sharename">UNC share name to connect to.</param> /// <param name="username">Username to use for connection.</param> /// <param name="password">Password to use for connection.</param> /// <param name="domain">Domain name to use for connetion. Specify the computer name for local system accounts.</param> public static void ConnectToNetworkShare(string sharename, string username, string password, string domain) { NETRESOURCE resource = new NETRESOURCE(); int result; resource.dwType = RESOURCETYPE_DISK; resource.lpRemoteName = sharename; if (domain.Length > 0) username = domain + "\\" + username; result = WNetAddConnection2(ref resource, password, username, 0); if (result != 0) throw new InvalidOperationException("Failed to connect to network share \"" + sharename + "\" as user " + username + " - " + WindowsApi.GetErrorMessage(result)); } /// <summary> /// Disconnects the specified network share. /// </summary> /// <param name="sharename">UNC share name to disconnect from.</param> public static void DisconnectFromNetworkShare(string sharename) { DisconnectFromNetworkShare(sharename, true); } /// <summary> /// Disconnects the specified network share. /// </summary> /// <param name="sharename">UNC share name to disconnect from.</param> /// <param name="force"><c>true</c> to force a disconnect; otherwise <c>false</c>.</param> public static void DisconnectFromNetworkShare(string sharename, bool force) { int result = WNetCancelConnection2(sharename, 0, force); if (result != 0) throw new InvalidOperationException("Failed to disconnect from network share \"" + sharename + "\" - " + WindowsApi.GetErrorMessage(result)); } #endif /// <summary> /// Determines whether the specified file name matches any of the given file specs (wildcards are defined as '*' or '?' characters). /// </summary> /// <param name="fileSpecs">The file specs used for matching the specified file name.</param> /// <param name="fileName">The file name to be tested against the specified file specs for a match.</param> /// <param name="ignoreCase"><c>true</c> to specify a case-insensitive match; otherwise <c>false</c>.</param> /// <returns><c>true</c> if the specified file name matches any of the given file specs; otherwise <c>false</c>.</returns> public static bool IsFilePatternMatch(string[] fileSpecs, string fileName, bool ignoreCase) { bool found = false; foreach (string fileSpec in fileSpecs) { if (IsFilePatternMatch(fileSpec, fileName, ignoreCase)) { found = true; break; } } return found; } /// <summary> /// Determines whether the specified file name matches the given file spec (wildcards are defined as '*' or '?' characters). /// </summary> /// <param name="fileSpec">The file spec used for matching the specified file name.</param> /// <param name="fileName">The file name to be tested against the specified file spec for a match.</param> /// <param name="ignoreCase"><c>true</c> to specify a case-insensitive match; otherwise <c>false</c>.</param> /// <returns><c>true</c> if the specified file name matches the given file spec; otherwise <c>false</c>.</returns> public static bool IsFilePatternMatch(string fileSpec, string fileName, bool ignoreCase) { return (new Regex(GetFilePatternRegularExpression(fileSpec), (ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None))).IsMatch(fileName); } /// <summary> /// Determines if the specified file name and path is valid. /// </summary> /// <param name="filePath">The file name with optional path to test for validity.</param> /// <returns><c>true</c> if the specified <paramref name="filePath"/> is a valid name; otherwise <c>false</c>.</returns> public static bool IsValidFileName(string filePath) { if (string.IsNullOrWhiteSpace(filePath)) return false; try { // Attempt to parse directory and file name - this will catch most issues string directory = Path.GetDirectoryName(filePath); string filename = Path.GetFileName(filePath); // Check for invalid directory characters if (!string.IsNullOrWhiteSpace(directory) && directory.IndexOfAny(Path.GetInvalidPathChars()) >= 0) return false; // Check for invalid file name characters if (string.IsNullOrWhiteSpace(filename) || filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) return false; // Recurse in to check validity of each directory name if (!string.IsNullOrWhiteSpace(directory) && !string.IsNullOrWhiteSpace(Path.GetFileName(directory))) return IsValidFileName(directory); } catch { // If you can't parse a file name or directory, file path is definitely not valid return false; } return true; } /// <summary> /// Gets the file name and extension from the specified file path. /// </summary> /// <param name="filePath">The file path from which the file name and extension is to be obtained.</param> /// <returns>File name and extension if the file path has it; otherwise empty string.</returns> public static string GetFileName(string filePath) { return Path.GetFileName(filePath); } /// <summary> /// Gets the extension from the specified file path. /// </summary> /// <param name="filePath">The file path from which the extension is to be obtained.</param> /// <returns>File extension.</returns> public static string GetExtension(string filePath) { return Path.GetExtension(RemovePathSuffix(filePath)); } /// <summary> /// Gets the file name without extension from the specified file path. /// </summary> /// <param name="filePath">The file path from which the file name is to be obtained.</param> /// <returns>File name without the extension if the file path has it; otherwise empty string.</returns> public static string GetFileNameWithoutExtension(string filePath) { return Path.GetFileNameWithoutExtension(RemovePathSuffix(filePath)); } /// <summary> /// Gets the size of the specified file. /// </summary> /// <param name="fileName">Name of file whose size is to be retrieved.</param> /// <returns>The size of the specified file.</returns> public static long GetFileLength(string fileName) { try { return (new FileInfo(fileName)).Length; } catch { return -1; } } /// <summary> /// Gets a list of files under the specified path. Search wildcard pattern (c:\Data\*.dat) can be used for /// including only the files matching the pattern or path wildcard pattern (c:\Data\*\*.dat) to indicate the /// inclusion of files under all subdirectories in the list. /// </summary> /// <param name="path">The path for which a list of files is to be returned.</param> /// <returns>A list of files under the given path.</returns> public static string[] GetFileList(string path) { string directory = GetDirectoryName(path); string filePattern = GetFileName(path); SearchOption options = SearchOption.TopDirectoryOnly; if (string.IsNullOrEmpty(filePattern)) { // No wildcard pattern was specified, so get a listing of all files. filePattern = "*.*"; } if (GetLastDirectoryName(directory) == "*") { // Path wildcard pattern is used to specify the option to include subdirectories. options = SearchOption.AllDirectories; directory = directory.Remove(directory.LastIndexOf("*")); } return Directory.GetFiles(directory, filePattern, options); } /// <summary> /// Gets a regular expression pattern that simulates wildcard matching for filenames (wildcards are defined as '*' or '?' characters). /// </summary> /// <param name="fileSpec">The file spec for which the regular expression pattern if to be generated.</param> /// <returns>Regular expression pattern that simulates wildcard matching for filenames.</returns> public static string GetFilePatternRegularExpression(string fileSpec) { // Replaces wildcard file patterns with their equivalent regular expression. fileSpec = fileSpec.Replace("\\", "\\u005C"); // Backslash in Regex means special sequence. Here, we really want a backslash. fileSpec = fileSpec.Replace(".", "\\u002E"); // Dot in Regex means any character. Here, we really want a dot. fileSpec = fileSpec.Replace("?", s_fileNameCharPattern); fileSpec = fileSpec.Replace("*", "(" + s_fileNameCharPattern + ")*"); return "^" + fileSpec + "$"; } /// <summary> /// Gets the directory information from the specified file path. /// </summary> /// <param name="filePath">The file path from which the directory information is to be obtained.</param> /// <returns>Directory information.</returns> public static string GetDirectoryName(string filePath) { return AddPathSuffix(Path.GetDirectoryName(filePath)); } /// <summary> /// Gets the last directory name from a file path. /// </summary> /// <param name="filePath">The file path from where the last directory name is to be retrieved.</param> /// <returns>The last directory name from a file path.</returns> /// <remarks> /// <see cref="GetLastDirectoryName(string)"/> would return sub2 from c:\windows\sub2\filename.ext. /// </remarks> public static string GetLastDirectoryName(string filePath) { // Test case should verify the following: // FilePath.GetLastDirectoryName(@"C:\Test\sub") == "Test" <-- sub assumed to be filename // FilePath.GetLastDirectoryName(@"C:\Test\sub\") == "sub" <-- sub assumed to be directory if (!string.IsNullOrEmpty(filePath)) { int index; char[] dirVolChars = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, Path.VolumeSeparatorChar }; // Remove file name and trailing directory seperator character from the file path. filePath = RemovePathSuffix(GetDirectoryName(filePath)); // Keep going through the file path until all directory seperator characters are removed. while ((index = filePath.IndexOfAny(dirVolChars)) > -1) { filePath = filePath.Substring(index + 1); } return filePath; } else { throw new ArgumentNullException("filePath"); } } /// <summary> /// Gets the absolute file path for the specified file name or relative file path. /// </summary> /// <param name="filePath">File name or relative file path.</param> /// <returns>Absolute file path for the specified file name or relative file path.</returns> public static string GetAbsolutePath(string filePath) { if (!Path.IsPathRooted(filePath)) { // The specified path is a relative one since it is not rooted. switch (Common.GetApplicationType()) { // Prepends the application's root to the file path. case ApplicationType.Web: filePath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, filePath); break; case ApplicationType.WindowsCui: case ApplicationType.WindowsGui: filePath = Path.Combine(GetDirectoryName(AssemblyInfo.EntryAssembly.Location), filePath); break; } } return RemovePathSuffix(filePath); } /// <summary> /// Determines if the specified <paramref name="filePath"/> is contained with the current executable path. /// </summary> /// <param name="filePath">File name or relative file path.</param> /// <returns><c>true</c> if the specified <paramref name="filePath"/> is contained with the current executable path; otherwise <c>false</c>.</returns> public static bool InApplicationPath(string filePath) { return GetAbsolutePath(filePath).StartsWith(GetAbsolutePath(""), StringComparison.InvariantCultureIgnoreCase); } /// <summary> /// Gets the path to the folder where data related to the current application can be stored. /// </summary> /// <returns>Path to the folder where data related to the current application can be stored.</returns> public static string GetApplicationDataFolder() { string rootFolder; ApplicationType platform = Common.GetApplicationType(); if (platform == ApplicationType.Web) { // Treat web application special. if (HostingEnvironment.ApplicationVirtualPath == "/") rootFolder = Path.Combine(Path.GetTempPath(), HostingEnvironment.SiteName); else rootFolder = Path.Combine(Path.GetTempPath(), HostingEnvironment.ApplicationVirtualPath.Trim('/')); // Create a user folder if ID is available. string userID = UserInfo.RemoteUserID; if (string.IsNullOrEmpty(userID)) { // ID is not available. return rootFolder; } else { // Remove domain from ID. if (!userID.Contains("\\")) return Path.Combine(rootFolder, userID); else return Path.Combine(rootFolder, userID.Remove(0, userID.IndexOf('\\') + 1)); } } else { // Use entry assembly for everything else. rootFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); if (string.IsNullOrEmpty(AssemblyInfo.EntryAssembly.Company)) return Path.Combine(rootFolder, AssemblyInfo.EntryAssembly.Name); else return Path.Combine(rootFolder, AssemblyInfo.EntryAssembly.Company + "\\" + AssemblyInfo.EntryAssembly.Name); } } /// <summary> /// Makes sure path is suffixed with standard <see cref="Path.DirectorySeparatorChar"/>. /// </summary> /// <param name="filePath">The file path to be suffixed.</param> /// <returns>Suffixed path.</returns> public static string AddPathSuffix(string filePath) { if (string.IsNullOrEmpty(filePath)) { filePath = Path.DirectorySeparatorChar.ToString(); } else { char suffixChar = filePath[filePath.Length - 1]; if (suffixChar != Path.DirectorySeparatorChar && suffixChar != Path.AltDirectorySeparatorChar) filePath += Path.DirectorySeparatorChar; } return filePath; } /// <summary> /// Makes sure path is not suffixed with <see cref="Path.DirectorySeparatorChar"/> or <see cref="Path.AltDirectorySeparatorChar"/>. /// </summary> /// <param name="filePath">The file path to be unsuffixed.</param> /// <returns>Unsuffixed path.</returns> public static string RemovePathSuffix(string filePath) { if (string.IsNullOrEmpty(filePath)) { filePath = "";