} // func OpenWrite /// <summary>Erzeugt die angegebene Datei (neu).</summary> /// <param name="file">Datei die angelegt werden soll.</param> /// <param name="notify">Zugriff auf die UI.</param> /// <param name="compressed">Soll die Datei gepackt sein.</param> /// <returns></returns> public static Stream OpenCreate(this FileInfo file, CmdletNotify notify, CompressMode compressed = CompressMode.Stored) { if (file.Exists) { var choices = new Collection <ChoiceDescription> { new ChoiceDescription("&Überschreiben"), new ChoiceDescription("&Abbrechen") }; if (notify.UI.PromptForChoice("Überschreiben", $"Datei '{file.Name}' überschreiben?", choices, 0) != 0) { notify.Abort(); } notify.SafeIO(file.Delete, $"Datei '{file.Name}' löschen."); } // Erzeuge die Datei im sicheren Context var src = notify.SafeIO(() => OpenWrite(file), $"Datei '{file.Name}' konnte nicht angelegt werden."); // Entpacke die Daten automatisch if (compressed == CompressMode.Compressed || (compressed == CompressMode.Auto && IsGZipFile(file.Name))) { return(new GZipStream(src, CompressionMode.Compress, false)); } else { return(src); } } // func OpenCreate
} // proc ZipFileItem private void GZipFileItem(CmdletNotify notify, CmdletProgress bar, Stream src, DirectoryInfo targetPath, FileIndexItem item) { using (var dst = new FileWrite(notify, new FileInfo(Path.Combine(targetPath.FullName, item.ArchiveName)), false, CompressMode.Auto)) { Stuff.CopyRawBytes(bar, item.RelativePath, src.Length, src, dst.Stream); dst.Commit(); } } // proc GZipFileItem
} // proc AddArchive private void UpdateMetaData(CmdletNotify notify, FileIndexItem src, FileInfo dst) { notify.SafeIO(() => { dst.LastAccessTimeUtc = src.LastAccessTimeUtc; dst.LastWriteTimeUtc = src.LastWriteTimeUtc; dst.CreationTimeUtc = src.CreationTimeUtc; dst.Attributes = src.Attributes; }, $"Setzen der Attribute {src.RelativePath} ist fehlgeschlagen."); } // proc UpdateMetaData
public FileWrite(CmdletNotify notify, FileInfo file, bool createMode, CompressMode compressed) { this.notify = notify; this.file = file; this.createMode = createMode; this.compressed = compressed; this.tempFile = new FileInfo(Path.Combine(file.Directory.FullName, Guid.NewGuid().ToString("N") + ".tmp")); if (compressed == CompressMode.Auto) { this.compressed = Stuff.IsGZipFile(file.Name) ? CompressMode.Compressed : CompressMode.Stored; } } // ctor
} // func OpenCreate /// <summary>Öffnet die Datei zum Schreiben.</summary> /// <param name="file">Datei die geöffnet werden soll.</param> /// <param name="notify">Zugriff auf die UI.</param> /// <param name="compressed">Soll die Datei gepackt sein.</param> /// <returns></returns> public static Stream OpenWrite(this FileInfo file, CmdletNotify notify, CompressMode compressed = CompressMode.Stored) { // Erzeuge die Datei im sicheren Context var src = notify.SafeIO(() => OpenWrite(file), $"Datei '{file.Name}' konnte nicht zum Schreiben geöffnet werden."); // Entpacke die Daten automatisch if (compressed == CompressMode.Compressed || (compressed == CompressMode.Auto && IsGZipFile(file.Name))) { return(new GZipStream(src, CompressionMode.Compress, false)); } else { return(src); } } // func OpenWrite
} // proc CloseZipStream private void ZipFileItem(CmdletNotify notify, CmdletProgress bar, Stream src, ZipOutputStream zip, FileIndexItem item) { var entry = new ZipEntry(ZipEntry.CleanName(item.RelativePath)); entry.DateTime = item.LastWriteTimeUtc; entry.Size = src.Length; entry.Comment = item.GetComment(); entry.CompressionMethod = ZipFile(item.RelativePath) ? CompressionMethod.Deflated : CompressionMethod.Stored; zip.PutNextEntry(entry); Stuff.CopyRawBytes(bar, item.RelativePath, src.Length, src, zip); zip.CloseEntry(); zip.Flush(); } // proc ZipFileItem
} // func OpenWrite /// <summary>Öffnet die Datei zum Lesen.</summary> /// <param name="file">Datei die geöffnet werden soll.</param> /// <param name="notify">Zugriff auf die UI.</param> /// <param name="compressed">Soll die Datei entpackt werden.</param> public static Stream OpenRead(this FileInfo file, CmdletNotify notify, CompressMode compressed = CompressMode.Stored, bool allowEmpty = false) { var desc = $"Datei '{file.Name}' kann nicht geöffnet werden."; var src = allowEmpty ? notify.SafeOpen(OpenRead, file, desc) : notify.SafeIO(() => OpenRead(file), desc); // Entpacke die Daten automatisch if (compressed == CompressMode.Compressed || (compressed == CompressMode.Auto && IsGZipFile(file.Name))) { return(new GZipStream(src, CompressionMode.Decompress, false)); } else { return(src); } } // func OpenRead
} // proc ReadIndex public void WriteIndex(CmdletNotify notify, string fileName) { var file = CreateIndexFileName(fileName); // erzeuge den index nicht direkt using (var dst = new FileWrite(notify, file, false, CompressMode.Auto)) using (var sw = new StreamWriter(dst.Stream, Encoding.Unicode)) { var csv = new CsvWriter(sw, FileIndexItem.csvDefinition); foreach (var cur in files.Values) { csv.WriteData(cur.GetLineData()); } dst.Commit(); } } // proc WriteIndex
} // func CreateIndexFileName public void ReadIndex(CmdletNotify notify, string fileName) { var file = CreateIndexFileName(fileName); if (file.Exists) { using (var sr = new StreamReader(file.OpenRead(notify, CompressMode.Auto), Encoding.Unicode, true)) { var csv = new CsvReader(sr, FileIndexItem.csvDefinition); while (true) { var cur = csv.ReadLine <FileIndexItem>(); if (cur == null) { break; } files.Add(cur.RelativePath, cur); } } } } // proc ReadIndex
public SendTarget(CmdletNotify notify) { this.notify = notify; }
public FileSendTarget(CmdletNotify notify, string target) : base(notify) { this.target = new DirectoryInfo(target); } // ctor
} // class FtpSendTarget #endregion protected override void ProcessRecord() { var notify = new CmdletNotify(this); using (var bar = notify.CreateStatus("Übertrage Dateien", $"Übertrage nach {Target}...")) { // create target provider SendTarget target; if (Target.StartsWith("ftp://", StringComparison.OrdinalIgnoreCase)) { target = new FtpSendTarget(notify, Target, false); } else if (Target.StartsWith("ftps://", StringComparison.OrdinalIgnoreCase)) { target = new FtpSendTarget(notify, "ftp" + Target.Substring(4), true); } else { target = new FileSendTarget(notify, Target); } // add credentials if (!String.IsNullOrEmpty(Username)) { target.PrepareUser(Username, Password); } // collect alle file to send var totalSize = 0L; var files = new List <FileListItem>(); var indexFile = (FileListItem)null; var indexRemoveFile = (FileListItem)null; var basePath = new DirectoryInfo(Source); foreach (var currentItem in new FileList(notify, basePath, Excludes)) { if (currentItem.RelativePath == "index.txt.gz") // search for index file, to upload it as the last file { indexFile = currentItem; totalSize += currentItem.FileInfo.Length; } else if (currentItem.RelativePath == "index_rm.txt") // and search for the remove file { indexRemoveFile = currentItem; } else { files.Add(currentItem); totalSize += currentItem.FileInfo.Length; } } files.Add(indexFile); // Upload files if (files.Count > 0) { bar.Maximum = totalSize; bar.StartRemaining(); foreach (var currentItem in files) { // upload file using (var dst = target.Create(currentItem.RelativePath, out var offset)) using (var src = currentItem.FileInfo.OpenRead(notify)) { src.Position = offset; Stuff.CopyRawBytes(bar, currentItem.RelativePath, currentItem.FileInfo.Length, src, dst); } // remove uploaded files if (RemoveSyncedFiles) { notify.SafeIO(currentItem.FileInfo.Delete, $"Lösche Datei {currentItem.RelativePath}."); } } bar.StopRemaining(); } // remove files if (indexRemoveFile != null) { using (var sr = new StreamReader(Stuff.OpenRead(indexRemoveFile.FileInfo, notify))) { var file = sr.ReadLine(); while (file != null) { target.Delete(file); file = sr.ReadLine(); } } notify.SafeIO(indexRemoveFile.FileInfo.Delete, $"Datei {indexRemoveFile.RelativePath} konnte nicht gelöscht werden."); } } } // proc ProcessRecord
public SendTarget(CmdletNotify notify) { this.notify = notify; } // ctor
public FtpSendTarget(CmdletNotify notify, string target, bool useSsl) : base(notify) { this.baseUri = new Uri(target, UriKind.Absolute); this.useSsl = useSsl; }
public FileSendTarget(CmdletNotify notify, string target) : base(notify) { this.target = new DirectoryInfo(target); }
private FileFilterRules excludes; // Dateien nicht enthalten sein sollen /// <summary>Erzeugt eine Dateiliste</summary> /// <param name="notify"></param> /// <param name="basePath">Basispfad</param> /// <param name="excludes">Dateien die ausgeschlossen werden sollen.</param> public FileList(CmdletNotify notify, DirectoryInfo basePath, params string[] excludes) { this.notify = notify; this.basePath = basePath; this.excludes = new FileFilterRules(excludes); } // ctor
} // proc UpdateMetaData protected override void ProcessRecord() { var notify = new CmdletNotify(this); var totalBytes = 0L; // Lese den Index ein var index = new FileIndex(); index.ReadIndex(notify, Path.Combine(Source, "index.txt.gz")); // Suche alle aktiven Archive var archives = new Dictionary <string, List <FileIndexItem> >(StringComparer.OrdinalIgnoreCase); using (var bar = notify.CreateStatus("Wiederherstellen eines Verzeichnisses", $"Wiederherstellen von {Source}...")) { var filter = new FileFilterRules(Filter); // Erzeuge Filter und entferne alle Dateien aus dem Index die dem nicht entsprechen if (filter.IsEmpty) { foreach (var c in index) { AddArchive(archives, c, ref totalBytes); } } else { var remove = new List <FileIndexItem>(); foreach (var c in index) { if (filter.IsFiltered(c.RelativePath)) { AddArchive(archives, c, ref totalBytes); } else { remove.Add(c); } } foreach (var c in remove) { index.RemoveEntry(c); } } // Entpacke die Archvie bar.StartRemaining(); bar.Maximum = totalBytes; foreach (var c in archives) { if (Stuff.IsGZipFile(c.Key) || Stuff.IsNoPackFile(c.Key)) // GZip-Datei { using (var src = Stuff.OpenRead(new FileInfo(Path.Combine(Source, c.Key)), notify, CompressMode.Auto)) { var srcFile = c.Value[0]; var dstFile = new FileInfo(Path.Combine(Target, srcFile.RelativePath)); using (var dst = Override ? Stuff.OpenWrite(dstFile, notify) : Stuff.OpenCreate(dstFile, notify)) { dst.SetLength(srcFile.Length); Stuff.CopyRawBytes(bar, srcFile.RelativePath, srcFile.Length, src, dst); } // Aktualisiere die Attribute UpdateMetaData(notify, srcFile, dstFile); } } else // zip-Datei { using (var zipStream = Stuff.OpenRead(new FileInfo(Path.Combine(Source, c.Key)), notify, CompressMode.Stored)) using (var zip = new ZipInputStream(zipStream)) { var srcEntry = zip.GetNextEntry(); while (srcEntry != null) { // Suche den passenden Index var srcIndex = c.Value.Find(c2 => String.Compare(srcEntry.Name, ZipEntry.CleanName(c2.RelativePath), StringComparison.OrdinalIgnoreCase) == 0); if (srcIndex != null) { var dstFile = new FileInfo(Path.Combine(Target, srcIndex.RelativePath)); using (var dst = Override ? Stuff.OpenWrite(dstFile, notify) : Stuff.OpenCreate(dstFile, notify)) { dst.SetLength(srcIndex.Length); Stuff.CopyRawBytes(bar, srcIndex.RelativePath, srcIndex.Length, zip, dst); } // Aktualisiere die Attribute UpdateMetaData(notify, srcIndex, dstFile); } else { zip.CloseEntry(); } // Schließe den Eintrag ab srcEntry = zip.GetNextEntry(); } } } } } } // proc ProcessRecord
public FtpSendTarget(CmdletNotify notify, string target, bool useSsl) : base(notify) { this.baseUri = new Uri(target, UriKind.Absolute); this.useSsl = useSsl; } // ctor