/// <inheritdoc /> /// <remarks>This is the really tricky clever part. It's built around the assumption that we can, at this point of /// the disposal, still seek back to the beginning of the stream and commit the update that was started in the /// constructor. It also assumes that other updates are going to be OK with being committed (if there are any).</remarks> protected override void Dispose(bool disposing) { if (Interlocked.Increment(ref _disposed) == 1) { var recurse = false; var copyToTemporaryFile = true; var isRooted = Path.IsPathRooted(_tarArchiveEntry.TarEntry.File); if (isRooted) { recurse = Directory.Exists(_tarArchiveEntry.TarEntry.File); copyToTemporaryFile = !recurse && !File.Exists(_tarArchiveEntry.TarEntry.File); } if (copyToTemporaryFile) { // operating on something that thus far is in-memory only using (var temporaryDirectory = new TemporaryDirectory()) { var subdirectory = Path.GetDirectoryName(_tarArchiveEntry.Name); if (!string.IsNullOrEmpty(subdirectory)) { Directory.CreateDirectory(Path.Combine(temporaryDirectory.Path, subdirectory)); } var entryFilePath = Path.Combine(temporaryDirectory.Path, _tarArchiveEntry.Name); Seek(0, SeekOrigin.Begin); using (var fileStream = new FileStream(entryFilePath, FileMode.Create, FileAccess.Write)) { CopyTo(fileStream); } var tarEntry = TarEntry.CreateEntryFromFile(entryFilePath); tarEntry.Name = _tarArchiveEntry.Name; recurse = IsDirectoryName(tarEntry.Name); _tarAccess.TarArchive.WriteEntry(tarEntry, recurse); _tarArchiveEntry.TarEntry = tarEntry; } } else { // already operating on an existing on-disk entity var tarEntry = _tarArchiveEntry.TarEntry; var tarArchive = _tarAccess.TarArchive; var rootPath = tarArchive.RootPath; if (recurse) { if (!string.IsNullOrEmpty(_tarAccess.RootLocation)) { tarArchive.RootPath = Path.GetDirectoryName(_tarAccess.RootLocation); } } try { tarArchive.WriteEntry(tarEntry, recurse); } finally { if (recurse) { tarArchive.RootPath = rootPath; } } } base.Dispose(disposing); } }
private NestedCompressedArchiveAccess(ICompressedArchiveAccess parentArchiveAccess, ICompressedArchiveAccess nestedArchiveAccess, TemporaryDirectory temporaryLocation) { ParentArchiveAccess = parentArchiveAccess; NestedAchiveAccess = nestedArchiveAccess; TemporaryLocation = temporaryLocation; }