// Copyright (C) 2024, The Duplicati Team // https://duplicati.com, hello@duplicati.com // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. using System; using System.Linq; using System.Collections.Generic; using Duplicati.Library.Interface; using Duplicati.Library.Common.IO; namespace Duplicati.Library.Compression { /// /// This class exposes a local directory as a file archive. /// Used only internally for debugging, cannot be used as a storage method. /// public class FileArchiveDirectory : ICompression { string m_folder; /// /// Constructs a new FileArchive /// /// The folder to base the archive on public FileArchiveDirectory(string basefolder) { m_folder = Util.AppendDirSeparator(basefolder); } #region IFileArchive Members /// /// Unsupported filename extension property, throws a MissingMethodException /// public string FilenameExtension { get { throw new MissingMethodException(); } } /// /// Unsupported displayname property, throws a MissingMethodException /// public string DisplayName { get { throw new MissingMethodException(); } } /// /// Unsupported description property, throws a MissingMethodException /// public string Description { get { throw new MissingMethodException(); } } /// /// Unsupported supported commands property, throws a MissingMethodException /// public IList SupportedCommands { get { throw new MissingMethodException(); } } /// /// Returns a list of files in the archive /// /// An optional prefix that is used to filter the list /// A filtered list of filenames public string[] ListFiles(string prefix) { if (prefix == null) prefix = ""; return Utility.Utility.EnumerateFiles(System.IO.Path.Combine(m_folder, prefix)).ToArray(); } /// /// Returns a list of files in the archive /// /// An optional prefix that is used to filter the list /// A filtered list of filenames public IEnumerable> ListFilesWithSize(string prefix) { if (prefix == null) prefix = ""; List> res = new List>(); foreach(string s in Utility.Utility.EnumerateFiles(System.IO.Path.Combine(m_folder, prefix))) res.Add(new KeyValuePair(s, new System.IO.FileInfo(s).Length)); return res; } /// /// Opens the file for reading /// /// The name of the file /// A stream with the file contents public System.IO.Stream OpenRead(string file) { return System.IO.File.OpenRead(System.IO.Path.Combine(m_folder, file)); } /// /// Creates a new empty file /// /// The name of the file to create /// A hint to the compressor as to how compressible the file data is /// The time the file was last written /// The stream used to access the file public System.IO.Stream CreateFile(string file, CompressionHint hint, DateTime lastWrite) { string path = System.IO.Path.Combine(m_folder, file); System.IO.Stream res = System.IO.File.Create(path); //TODO: This should actually be set when closing the stream System.IO.File.SetLastWriteTime(path, lastWrite); return res; } /// /// Returns a value that indicates if the file exists /// /// The name of the file to test existence for /// True if the file exists, false otherwise public bool FileExists(string file) { return System.IO.File.Exists(System.IO.Path.Combine(m_folder, file)); } /// /// Gets the current size of the archive /// public long Size { get { return Utility.Utility.GetDirectorySize(m_folder); } } /// /// Gets the last write time for a file /// /// The name of the file to query /// The last write time for the file public DateTime GetLastWriteTime(string file) { return System.IO.File.GetLastWriteTime(System.IO.Path.Combine(m_folder, file)); } /// /// The size of the current unflushed buffer /// public long FlushBufferSize { get { return 0; } } #endregion #region IDisposable Members /// /// Disposes the instance /// public void Dispose() { m_folder = null; } #endregion } }