// Copyright (C) Stichting Deltares 2016. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security;
using Core.Common.Utils.Builders;
using Core.Common.Utils.Properties;
namespace Core.Common.Utils
{
///
/// Class with reusable file and folder related utility methods.
///
public static class IOUtils
{
///
/// Validates the folder path.
///
/// The folder path to be validated.
/// true if the folder path is valid; false otherwise.
/// A valid folder path:
///
/// - is not empty nor contains only whitespaces.
/// - has no access rights to that location.
/// - isn't too long.
/// - does not contain an invalid ':' character.
///
public static bool IsValidFolderPath(string path)
{
try
{
ValidateFolderPath(path);
}
catch (ArgumentException)
{
return false;
}
return true;
}
///
/// Validates the folder path.
///
/// The folder path to be validated.
/// Thrown when:
///
/// - The folder path is empty or contains only whitespaces.
/// - Caller has no access rights to the folder path.
/// - The folder path is too long.
/// - The folder path contains an invalid ':' character.
///
public static void ValidateFolderPath(string path)
{
try
{
string fullPath = GetFullPath(path);
}
catch (ArgumentException exception)
{
string message = new DirectoryWriterErrorMessageBuilder(path)
.Build(exception.Message);
throw new ArgumentException(message, exception.InnerException);
}
}
///
/// Validates the file path.
///
/// The file path to be validated.
/// Thrown when is invalid.
/// A valid path:
///
/// - is not empty or null,
/// - does not consist out of only whitespace characters,
/// - does not contain an invalid character,
/// - does not end with a directory or path separator (empty file name).
///
///
public static void ValidateFilePath(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
string message = new FileReaderErrorMessageBuilder(path).Build(Resources.Error_Path_must_be_specified);
throw new ArgumentException(message);
}
string name;
try
{
name = Path.GetFileName(path);
}
catch (ArgumentException exception)
{
string message = new FileReaderErrorMessageBuilder(path)
.Build(Resources.Error_Path_cannot_contain_invalid_characters);
throw new ArgumentException(message, exception);
}
if (string.IsNullOrEmpty(name))
{
string message = new FileReaderErrorMessageBuilder(path).Build(Resources.Error_Path_must_not_point_to_empty_file_name);
throw new ArgumentException(message);
}
}
///
/// Validates the file path.
///
/// The file path to be validated.
/// true if the file path is valid, false otherwise.
/// A valid path:
///
/// - contains not only whitespace,
/// - does not contain an invalid character,
/// - is not empty or null,
/// - does not end with a directory or path separator (empty file name).
///
public static bool IsValidFilePath(string path)
{
try
{
ValidateFilePath(path);
}
catch (ArgumentException)
{
return false;
}
return true;
}
///
/// Searches the files in that match and
/// deletes the files older than days.
///
/// The directory to search.
/// The search string to match against the names of files in path.
/// The maximum number days since the file was created.
/// Thrown when or is null, is a zero-length string,
/// contains only white space, or contains one or more invalid characters.
/// Thrown when an error occurred while trying to search and delete files in .
public static void DeleteOldFiles(string path, string searchPattern, int numberOfDaysToKeepFiles)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException(@"No valid value for 'path'.", nameof(path));
}
if (string.IsNullOrWhiteSpace(searchPattern))
{
throw new ArgumentException(@"No valid value for 'searchPattern'.", nameof(searchPattern));
}
try
{
foreach (string logFile in Directory.GetFiles(path, searchPattern).Where(
l => (DateTime.Now - File.GetCreationTime(l)).TotalDays > numberOfDaysToKeepFiles))
{
File.Delete(logFile);
}
}
catch (Exception e)
{
if (e is ArgumentException || e is IOException || e is NotSupportedException || e is UnauthorizedAccessException)
{
string message = string.Format(CultureInfo.CurrentCulture,
Resources.IOUtils_DeleteOldFiles_Error_occurred_deleting_files_in_folder_0,
path);
throw new IOException(message, e);
}
throw;
}
}
///
/// Creates a file at if it does not exist already.
///
/// The file path to be created.
/// Thrown when is invalid.
/// A valid path:
///
/// - is not empty or null,
/// - does not consist out of only whitespace characters,
/// - does not contain an invalid character,
/// - does not end with a directory or path separator (empty file name).
///
public static void CreateFileIfNotExists(string path)
{
ValidateFilePath(path);
var canWrite = false;
try
{
using (var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
canWrite = fs.CanWrite;
}
}
finally
{
if (!canWrite)
{
throw new ArgumentException(string.Format(Resources.Error_General_output_error_0, path), nameof(path));
}
}
}
///
/// Returns the absolute path for the specified path string.
///
/// The file or directory for which to obtain absolute path information.
/// The fully qualified location of path, such as "C:\MyFile.txt".
/// Thrown when:
///
/// - The path is null, empty or contains only whitespaces.
/// - The caller has no access rights to the path.
/// - The path is too long.
/// - The path contains a ':' that is not part of a volume identifier.
///
public static string GetFullPath(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException(Resources.IOUtils_Path_cannot_be_empty);
}
try
{
return Path.GetFullPath(path);
}
catch (ArgumentException exception)
{
throw new ArgumentException(Resources.Error_Path_cannot_contain_invalid_characters,
exception);
}
catch (SecurityException exception)
{
throw new ArgumentException(Resources.IOUtils_No_access_rights_to_path,
exception);
}
catch (PathTooLongException exception)
{
throw new ArgumentException(Resources.IOUtils_Path_too_long,
exception);
}
catch (NotSupportedException exception)
{
throw new ArgumentException(Resources.IOUtils_Path_contains_invalid_character,
exception);
}
}
}
}