using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using gehGassi.Core.Interfaces; namespace gehGassi.Core.Services { /// /// 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 /// public class LocalFileShareService : IFileShareService { private readonly string _root; /// /// Erstellt eine Instanz /// /// Root-Folder für Shares [ExcludeFromCodeCoverage] public LocalFileShareService(string root) { _root = root; if (!Directory.Exists(_root)) { Directory.CreateDirectory(_root); } } /// /// Auflisten der Ordner in einem Ordner /// /// Name des Shares /// Ordner /// Liste der Ordner im Share public List ListFolders(string shareName, string folder) { var result = new List(); 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; } /// /// Gibt Informationen über einen Ordner zurück /// /// Name des Shares /// Ordner /// Ordner oder null 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; } /// /// Auflisten der Dateien in einem Ordner /// /// Name des Shares /// Ordner /// Liste der Dateien im Ordner public List ListFiles(string shareName, string folder) { var result = new List(); 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; } /// /// Gibt Informationen über eine Datei zurück /// /// Name des Shares /// Dateiname relativ /// FileInfo oder null 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; } /// /// Auflisten der Dateien und Ordner in einem Ordner /// /// Name des Shares /// Ordner /// Liste Dateien und Liste Ordner public (List, List) ListFilesAndFolders(string shareName, string folder) { throw new NotImplementedException(); } /// /// Anlegen eines Ordners. /// /// Name des Shares /// Neuer Ordner /// true wenn erfolgreich, false sonst 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; } /// /// Speichern einer Datei /// /// Name des Shares /// Dateiname mit Ordnern relativ /// Datei /// true wenn überschrieben werden soll, false sonst /// true wenn erfolgreich, false sonst 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; } /// /// Holt eine Datei /// /// Name des Shares /// Dateiname mit Ordnern relativ /// Datei oder null, wenn nicht gefunden 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; } /// /// Holt eine Datei als Stream /// /// Name des Shares /// Dateiname mit Ordnern relativ /// Stream oder null, wenn nicht gefunden 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; } /// /// Holt eine Datei als Stream /// /// Name des Shares /// Dateiname mit Ordnern relativ /// Wo soll gestartet werden /// WoEnde /// Stream oder null, wenn nicht gefunden 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; } /// /// Umbenennen einer Datei /// /// Name des Shares /// Aktueller Dateiname /// Neuer Dateiname /// Soll eine Kopie gemacht werden? Wenn nicht wird die Quelldatei gelöscht /// true wenn erfolgreich, false sonst 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; } /// /// Umbenennen eines Ordners /// /// Name des Shares /// Aktueller Ordnername /// Neuer Ordnername /// Soll eine Kopie gemacht werden? Wenn nicht wird der QuellOrdner gelöscht /// true wenn erfolgreich, false sonst 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; } /// /// Umbenennen eines Ordners - Ohne TransferManager /// /// Name des Shares /// Aktueller Ordnername /// Neuer Ordnername /// Soll eine Kopie gemacht werden? Wenn nicht wird der QuellOrdner gelöscht /// true wenn erfolgreich, false sonst 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; } /// /// Löschen einer Datei /// /// Name des Shares /// Dateiname mit Ordnern relativ /// true wenn erfolgreich, false sonst 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; } /// /// Löschen eines Ordners /// /// Name des Shares /// Ordner /// true wenn erfolgreich, false sonst 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; } /// /// Löschen eines Shares /// /// Name des Shares /// true wenn erfolgreich, false sonst 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; } /// /// Gibt die größe des Ordners (Dateien) als byte zurück /// /// Name des Shares /// Ordner /// Liste der Ordner im Share 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; } /// /// Deep-Copy eines Ordners /// /// Quelle /// Ziel /// Sollen Unterordner und Daten auch kopiert werden [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); } } } /// /// Hilfsmethode - rukrsiv Ordnergrößen anhand der Dateien berechnen /// /// Ordner /// Größe in bytes [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; } } } }