gehgassi_backend/gehGassi.Core/Services/LocalFileShareService.cs

668 lines
24 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using gehGassi.Core.Interfaces;
namespace gehGassi.Core.Services
{
/// <summary>
/// Service der die Verwaltung von Dateien als share ermöglicht.
/// Alle Ordner und Dateinamen sind relativ anzugeben.
/// z.B. test/Ordner1/order2
/// z.B. test/Ordner1/test.png
/// </summary>
public class LocalFileShareService : IFileShareService
{
private readonly string _root;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="root">Root-Folder für Shares</param>
[ExcludeFromCodeCoverage]
public LocalFileShareService(string root)
{
_root = root;
if (!Directory.Exists(_root))
{
Directory.CreateDirectory(_root);
}
}
/// <summary>
/// Auflisten der Ordner in einem Ordner
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="folder">Ordner</param>
/// <returns>Liste der Ordner im Share</returns>
public List<FolderResult> ListFolders(string shareName, string folder)
{
var result = new List<FolderResult>();
if (!string.IsNullOrWhiteSpace(shareName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var directory = sharePath;
if (!string.IsNullOrWhiteSpace(folder))
directory = Path.Combine(sharePath, folder);
var folders = Directory.GetDirectories(directory);
foreach (var folderInfo in folders)
{
var info = new DirectoryInfo(folderInfo);
var item = new FolderResult
{
Name = folderInfo.Replace(directory, "").TrimStart('\\'),
LastModified = info.LastWriteTimeUtc,
Created = info.CreationTimeUtc,
HasSubfolders = info.GetDirectories().Length > 0
};
result.Add(item);
}
}
return result;
}
/// <summary>
/// Gibt Informationen über einen Ordner zurück
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="folder">Ordner</param>
/// <returns>Ordner oder null</returns>
public FolderResult GetFolderInfo(string shareName, string folder)
{
if (!string.IsNullOrWhiteSpace(shareName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var folderInfo = sharePath;
if (!string.IsNullOrWhiteSpace(folder))
folderInfo = Path.Combine(sharePath, folder);
var info = new DirectoryInfo(folderInfo);
var item = new FolderResult
{
Name = folder,
LastModified = info.LastWriteTimeUtc,
Created = info.CreationTimeUtc,
HasSubfolders = info.GetDirectories().Length > 0
};
return item;
}
return null;
}
/// <summary>
/// Auflisten der Dateien in einem Ordner
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="folder">Ordner</param>
/// <returns>Liste der Dateien im Ordner</returns>
public List<FileResult> ListFiles(string shareName, string folder)
{
var result = new List<FileResult>();
if (!string.IsNullOrWhiteSpace(shareName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var directory = sharePath;
if (!string.IsNullOrWhiteSpace(folder))
directory = Path.Combine(sharePath, folder);
var files = Directory.GetFiles(directory);
foreach (var file in files)
{
var info = new FileInfo(file);
var item = new FileResult
{
Name = file.Replace(directory, "").TrimStart('\\'),
LastModified = info.LastWriteTimeUtc,
Created = info.CreationTimeUtc,
Size = info.Length
};
result.Add(item);
}
}
return result;
}
/// <summary>
/// Gibt Informationen über eine Datei zurück
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="fileName">Dateiname relativ</param>
/// <returns>FileInfo oder null</returns>
public FileResult GetFileInfo(string shareName, string fileName)
{
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(fileName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var filePath = sharePath;
if (!string.IsNullOrWhiteSpace(fileName))
filePath = Path.Combine(sharePath, fileName);
if (File.Exists(filePath))
{
var info = new FileInfo(filePath);
var item = new FileResult
{
Name = fileName,
LastModified = info.LastWriteTimeUtc,
Created = info.CreationTimeUtc,
Size = info.Length
};
return item;
}
}
return null;
}
/// <summary>
/// Auflisten der Dateien und Ordner in einem Ordner
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="folder">Ordner</param>
/// <returns>Liste Dateien und Liste Ordner</returns>
public (List<FileResult>, List<FolderResult>) ListFilesAndFolders(string shareName, string folder)
{
throw new NotImplementedException();
}
/// <summary>
/// Anlegen eines Ordners.
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="newfolderName">Neuer Ordner</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
public bool CreateFolder(string shareName, string newfolderName)
{
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(newfolderName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var folder = sharePath;
if (!string.IsNullOrWhiteSpace(folder))
folder = Path.Combine(sharePath, newfolderName);
try
{
Directory.CreateDirectory(folder);
return true;
}
catch
{
// ignored
}
}
return false;
}
/// <summary>
/// Speichern einer Datei
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="fileName">Dateiname mit Ordnern relativ</param>
/// <param name="file">Datei</param>
/// <param name="overwrite">true wenn überschrieben werden soll, false sonst</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
public bool Store(string shareName, string fileName, byte[] file, bool overwrite = false)
{
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(fileName) && file != null && file.Length > 0)
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var filePath = sharePath;
if (!string.IsNullOrWhiteSpace(fileName))
filePath = Path.Combine(sharePath, fileName);
try
{
File.WriteAllBytes(filePath, file);
return true;
}
catch
{
// ignored
}
}
return false;
}
/// <summary>
/// Holt eine Datei
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="fileName">Dateiname mit Ordnern relativ</param>
/// <returns>Datei oder null, wenn nicht gefunden</returns>
public byte[] Get(string shareName, string fileName)
{
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(fileName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var filePath = sharePath;
if (!string.IsNullOrWhiteSpace(fileName))
filePath = Path.Combine(sharePath, fileName);
if (File.Exists(filePath))
return File.ReadAllBytes(filePath);
}
return null;
}
/// <summary>
/// Holt eine Datei als Stream
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="fileName">Dateiname mit Ordnern relativ</param>
/// <returns>Stream oder null, wenn nicht gefunden</returns>
public Stream GetStream(string shareName, string fileName)
{
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(fileName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var filePath = sharePath;
if (!string.IsNullOrWhiteSpace(fileName))
filePath = Path.Combine(sharePath, fileName);
if (File.Exists(filePath))
return File.OpenRead(filePath);
}
return null;
}
/// <summary>
/// Holt eine Datei als Stream
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="fileName">Dateiname mit Ordnern relativ</param>
/// <param name="start">Wo soll gestartet werden</param>
/// <param name="end">WoEnde</param>
/// <returns>Stream oder null, wenn nicht gefunden</returns>
public Stream GetStream(string shareName, string fileName, long start, long end)
{
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(fileName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var filePath = sharePath;
if (!string.IsNullOrWhiteSpace(fileName))
filePath = Path.Combine(sharePath, fileName);
if (File.Exists(filePath))
return File.OpenRead(filePath);
}
return null;
}
/// <summary>
/// Umbenennen einer Datei
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="fileName">Aktueller Dateiname</param>
/// <param name="newFileName">Neuer Dateiname</param>
/// <param name="copy">Soll eine Kopie gemacht werden? Wenn nicht wird die Quelldatei gelöscht</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
public bool RenameFile(string shareName, string fileName, string newFileName, bool copy)
{
var success = false;
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(fileName) && !string.IsNullOrWhiteSpace(newFileName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var filePath = sharePath;
if (!string.IsNullOrWhiteSpace(fileName))
filePath = Path.Combine(sharePath, fileName);
var newFilePath = sharePath;
if (!string.IsNullOrWhiteSpace(newFileName))
newFilePath = Path.Combine(sharePath, newFileName);
if (File.Exists(filePath) && !File.Exists(newFilePath))
{
try
{
if(!copy)
File.Move(filePath, newFilePath);
else
File.Copy(filePath, newFilePath);
success = true;
}
catch
{
success = false;
}
}
}
return success;
}
/// <summary>
/// Umbenennen eines Ordners
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="folder">Aktueller Ordnername</param>
/// <param name="newFolder">Neuer Ordnername</param>
/// <param name="copy">Soll eine Kopie gemacht werden? Wenn nicht wird der QuellOrdner gelöscht</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
public bool RenameFolder(string shareName, string folder, string newFolder, bool copy)
{
var success = false;
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(folder) && !string.IsNullOrWhiteSpace(newFolder))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var folderPath = sharePath;
if (!string.IsNullOrWhiteSpace(folder))
folderPath = Path.Combine(sharePath, folder);
var newFolderPath = sharePath;
if (!string.IsNullOrWhiteSpace(newFolder))
newFolderPath = Path.Combine(sharePath, newFolder);
if (Directory.Exists(folderPath))
{
try
{
if (!copy && !Directory.Exists(newFolderPath))
Directory.Move(folderPath, newFolderPath);
else
DirectoryCopy(folderPath, newFolderPath, true);
success = true;
}
catch
{
success = false;
}
}
}
return success;
}
/// <summary>
/// Umbenennen eines Ordners - Ohne TransferManager
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="folder">Aktueller Ordnername</param>
/// <param name="newFolder">Neuer Ordnername</param>
/// <param name="copy">Soll eine Kopie gemacht werden? Wenn nicht wird der QuellOrdner gelöscht</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
public bool RenameFolderEx(string shareName, string folder, string newFolder, bool copy)
{
var success = false;
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(folder) && !string.IsNullOrWhiteSpace(newFolder))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var folderPath = sharePath;
if (!string.IsNullOrWhiteSpace(folder))
folderPath = Path.Combine(sharePath, folder);
var newFolderPath = sharePath;
if (!string.IsNullOrWhiteSpace(newFolder))
newFolderPath = Path.Combine(sharePath, newFolder);
if (Directory.Exists(folderPath))
{
try
{
if (!copy && !Directory.Exists(newFolderPath))
Directory.Move(folderPath, newFolderPath);
else
DirectoryCopy(folderPath, newFolderPath, true);
success = true;
}
catch
{
success = false;
}
}
}
return success;
}
/// <summary>
/// Löschen einer Datei
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="fileName">Dateiname mit Ordnern relativ</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
public bool DeleteFile(string shareName, string fileName)
{
var success = false;
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(fileName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var filePath = sharePath;
if (!string.IsNullOrWhiteSpace(fileName))
filePath = Path.Combine(sharePath, fileName);
if (File.Exists(filePath))
{
try
{
File.Delete(filePath);
success = true;
}
catch
{
success = false;
}
}
}
return success;
}
/// <summary>
/// Löschen eines Ordners
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="folder">Ordner</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
public bool DeleteFolder(string shareName, string folder)
{
var success = false;
if (!string.IsNullOrWhiteSpace(shareName) && !string.IsNullOrWhiteSpace(folder))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var folderPath = sharePath;
if (!string.IsNullOrWhiteSpace(folder))
folderPath = Path.Combine(sharePath, folder);
if (Directory.Exists(folderPath))
{
try
{
Directory.Delete(folderPath,true);
success = true;
}
catch
{
success = false;
}
}
}
return success;
}
/// <summary>
/// Löschen eines Shares
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
public bool DeleteShare(string shareName)
{
var success = false;
if (!string.IsNullOrWhiteSpace(shareName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
if (Directory.Exists(sharePath))
{
try
{
Directory.Delete(sharePath, true);
success = true;
}
catch
{
success = false;
}
}
}
return success;
}
/// <summary>
/// Gibt die größe des Ordners (Dateien) als byte zurück
/// </summary>
/// <param name="shareName">Name des Shares</param>
/// <param name="folder">Ordner</param>
/// <returns>Liste der Ordner im Share</returns>
public long GetFolderSize(string shareName, string folder)
{
var size = 0L;
if (!string.IsNullOrWhiteSpace(shareName))
{
var sharePath = Path.Combine(_root, shareName);
if (!Directory.Exists(sharePath))
Directory.CreateDirectory(sharePath);
var directory = sharePath;
if (!string.IsNullOrWhiteSpace(folder))
directory = Path.Combine(sharePath, folder);
var directories = Directory.GetDirectories(directory);
foreach (var dir in directories)
{
InternalGetFolderSize(dir, ref size);
}
var files = Directory.GetFiles(directory);
foreach (var file in files)
{
var info = new FileInfo(file);
size += info.Length;
}
}
return size;
}
/// <summary>
/// Deep-Copy eines Ordners
/// </summary>
/// <param name="sourceDirName">Quelle</param>
/// <param name="destDirName">Ziel</param>
/// <param name="copySubDirs">Sollen Unterordner und Daten auch kopiert werden</param>
[ExcludeFromCodeCoverage]
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
var dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
var dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
Directory.CreateDirectory(destDirName);
// Get the files in the directory and copy them to the new location.
var files = dir.GetFiles();
foreach (var file in files)
{
var tempPath = Path.Combine(destDirName, file.Name);
file.CopyTo(tempPath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (var subdir in dirs)
{
string tempPath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, tempPath, true);
}
}
}
/// <summary>
/// Hilfsmethode - rukrsiv Ordnergrößen anhand der Dateien berechnen
/// </summary>
/// <param name="directory">Ordner</param>
/// <param name="size">Größe in bytes</param>
[ExcludeFromCodeCoverage]
private void InternalGetFolderSize(string directory, ref long size)
{
var directories = Directory.GetDirectories(directory);
foreach (var dir in directories)
{
InternalGetFolderSize(dir, ref size);
}
var files = Directory.GetFiles(directory);
foreach (var file in files)
{
var info = new FileInfo(file);
size += info.Length;
}
}
}
}