You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
10 KiB
239 lines
10 KiB
//
|
|
// FileManager.cs
|
|
//
|
|
// Author: Kees van Spelde <sicos2002@hotmail.com>
|
|
//
|
|
// Copyright (c) 2013-2018 Magic-Sessions. (www.magic-sessions.com)
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
//
|
|
|
|
using System;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
namespace MsgReader.Helpers
|
|
{
|
|
/// <summary>
|
|
/// This class contains file management functions that are not available in the .NET framework
|
|
/// </summary>
|
|
internal static class FileManager
|
|
{
|
|
#region Consts
|
|
/// <summary>
|
|
/// The max path length in Windows
|
|
/// </summary>
|
|
private const int MaxPath = 248;
|
|
#endregion
|
|
|
|
#region CheckForBackSlash
|
|
/// <summary>
|
|
/// Check if there is a backslash at the end of the string and if not add it
|
|
/// </summary>
|
|
/// <param name="line"></param>
|
|
/// <returns></returns>
|
|
public static string CheckForBackSlash(string line)
|
|
{
|
|
if (line[line.Length - 1] == Path.DirectorySeparatorChar || line[line.Length - 1] == Path.AltDirectorySeparatorChar)
|
|
return line;
|
|
|
|
return line + Path.DirectorySeparatorChar;
|
|
}
|
|
#endregion
|
|
|
|
#region ValidateLongFileName
|
|
/// <summary>
|
|
/// Validates the length of <paramref name="fileName"/>, when this is longer then <see cref="MaxPath"/> chars it will be truncated.
|
|
/// </summary>
|
|
/// <param name="fileName">The filename with path</param>
|
|
/// <param name="extraTruncateSize">Optional extra truncate size, when not used the filename is truncated until it fits</param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ArgumentException">Raised when no path or file name is given in the <paramref name="fileName"/></exception>
|
|
/// <exception cref="PathTooLongException">Raised when it is not possible to truncate the <paramref name="fileName"/></exception>
|
|
public static string ValidateLongFileName(string fileName, int extraTruncateSize = -1)
|
|
{
|
|
var fileNameWithoutExtension = GetFileNameWithoutExtension(fileName);
|
|
|
|
if (string.IsNullOrWhiteSpace(fileNameWithoutExtension))
|
|
throw new ArgumentException(@"No file name is given, e.g. c:\temp\temp.txt", nameof(fileName));
|
|
|
|
var extension = GetExtension(fileName);
|
|
|
|
if (string.IsNullOrWhiteSpace(extension))
|
|
extension = string.Empty;
|
|
|
|
var path = GetDirectoryName(fileName);
|
|
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
throw new ArgumentException(@"No path is given, e.g. c:\temp\temp.txt", nameof(fileName));
|
|
|
|
path = CheckForBackSlash(path);
|
|
|
|
if (fileName.Length <= MaxPath)
|
|
return fileName;
|
|
|
|
var maxFileNameLength = MaxPath - path.Length - extension.Length;
|
|
if (extraTruncateSize != -1)
|
|
maxFileNameLength -= extraTruncateSize;
|
|
|
|
if (maxFileNameLength < 1)
|
|
throw new PathTooLongException("Unable the truncate the fileName '" + fileName + "', current size '" +
|
|
fileName.Length + "'");
|
|
|
|
return path + fileNameWithoutExtension.Substring(0, maxFileNameLength) + extension;
|
|
}
|
|
#endregion
|
|
|
|
#region GetExtension
|
|
/// <summary>
|
|
/// Returns the extension of the specified <paramref name="path"/> string
|
|
/// </summary>
|
|
/// <param name="path">The path of the file</param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ArgumentException">Raised when no path is given</exception>
|
|
public static string GetExtension(string path)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
throw new ArgumentException("path");
|
|
|
|
var splittedPath = path.Split(Path.DirectorySeparatorChar);
|
|
var fileName = splittedPath[splittedPath.Length - 1];
|
|
|
|
var index = fileName.LastIndexOf(".", StringComparison.Ordinal);
|
|
|
|
return index == -1
|
|
? string.Empty
|
|
: fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal), fileName.Length - index);
|
|
}
|
|
#endregion
|
|
|
|
#region GetFileNameWithoutExtension
|
|
/// <summary>
|
|
/// Returns the file name of the specified <paramref name="path"/> string without the extension
|
|
/// </summary>
|
|
/// <param name="path">The path of the file</param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ArgumentException"></exception>
|
|
public static string GetFileNameWithoutExtension(string path)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
throw new ArgumentException(@"No path given", nameof(path));
|
|
|
|
var splittedPath = path.Split(Path.DirectorySeparatorChar);
|
|
var fileName = splittedPath[splittedPath.Length - 1];
|
|
return !fileName.Contains(".")
|
|
? fileName
|
|
: fileName.Substring(0, fileName.LastIndexOf(".", StringComparison.Ordinal));
|
|
}
|
|
#endregion
|
|
|
|
#region GetDirectoryName
|
|
/// <summary>
|
|
/// Returns the directory information for the specified <paramref name="path"/> string
|
|
/// </summary>
|
|
/// <param name="path">The path of a file or directory</param>
|
|
/// <returns></returns>
|
|
public static string GetDirectoryName(string path)
|
|
{
|
|
//GetDirectoryName('C:\MyDir\MySubDir\myfile.ext') returns 'C:\MyDir\MySubDir'
|
|
//GetDirectoryName('C:\MyDir\MySubDir') returns 'C:\MyDir'
|
|
//GetDirectoryName('C:\MyDir\') returns 'C:\MyDir'
|
|
//GetDirectoryName('C:\MyDir') returns 'C:\'
|
|
//GetDirectoryName('C:\') returns ''
|
|
|
|
var splittedPath = path.Split(Path.DirectorySeparatorChar);
|
|
|
|
if (splittedPath.Length <= 1)
|
|
return string.Empty;
|
|
|
|
var result = splittedPath[0];
|
|
|
|
for (var i = 1; i < splittedPath.Length - 1; i++)
|
|
result += Path.DirectorySeparatorChar + splittedPath[i];
|
|
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
#region FileExistsMakeNew
|
|
/// <summary>
|
|
/// Checks if a file already exists and if so adds a number until the file is unique
|
|
/// </summary>
|
|
/// <param name="fileName">The file to check</param>
|
|
/// <param name="validateLongFileName">When true validation will be performed on the max path lengt</param>
|
|
/// <param name="extraTruncateSize"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ArgumentException">Raised when no path or file name is given in the <paramref name="fileName"/></exception>
|
|
/// <exception cref="PathTooLongException">Raised when it is not possible to truncate the <paramref name="fileName"/></exception>
|
|
public static string FileExistsMakeNew(string fileName, bool validateLongFileName = true, int extraTruncateSize = -1)
|
|
{
|
|
var extension = GetExtension(fileName);
|
|
var path = CheckForBackSlash(GetDirectoryName(fileName));
|
|
|
|
var tempFileName = validateLongFileName ? ValidateLongFileName(fileName, extraTruncateSize) : fileName;
|
|
|
|
var i = 2;
|
|
while (File.Exists(tempFileName))
|
|
{
|
|
tempFileName = validateLongFileName ? ValidateLongFileName(tempFileName, extraTruncateSize) : tempFileName;
|
|
var fileNameWithoutExtension = GetFileNameWithoutExtension(tempFileName);
|
|
tempFileName = path + fileNameWithoutExtension + "_" + i + extension;
|
|
i += 1;
|
|
}
|
|
|
|
return tempFileName;
|
|
}
|
|
#endregion
|
|
|
|
#region RemoveInvalidFileNameChars
|
|
/// <summary>
|
|
/// Removes illegal filename characters
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public static string RemoveInvalidFileNameChars(string fileName)
|
|
{
|
|
return Path.GetInvalidFileNameChars().Aggregate(fileName, (current, c) => current.Replace(c.ToString(CultureInfo.InvariantCulture), string.Empty));
|
|
}
|
|
#endregion
|
|
|
|
#region GetFileSizeString
|
|
/// <summary>
|
|
/// Gives the size of a file in Windows format (GB, MB, KB, Bytes)
|
|
/// </summary>
|
|
/// <param name="bytes">Filesize in bytes</param>
|
|
/// <returns></returns>
|
|
public static string GetFileSizeString(double bytes)
|
|
{
|
|
var size = "0 Bytes";
|
|
if (bytes >= 1073741824.0)
|
|
size = String.Format(CultureInfo.InvariantCulture, "{0:##.##}", bytes / 1073741824.0) + " GB";
|
|
else if (bytes >= 1048576.0)
|
|
size = String.Format(CultureInfo.InvariantCulture, "{0:##.##}", bytes / 1048576.0) + " MB";
|
|
else if (bytes >= 1024.0)
|
|
size = String.Format(CultureInfo.InvariantCulture, "{0:##.##}", bytes / 1024.0) + " KB";
|
|
else if (bytes > 0 && bytes < 1024.0)
|
|
size = bytes + " Bytes";
|
|
|
|
return size;
|
|
}
|
|
#endregion
|
|
}
|
|
} |