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;
}
}
}
}