public static IEnumerable <CacheBlockFileFileEntry> GetFileEntries(string directory, bool mixed) { if (directory is null) { throw new ArgumentNullException(nameof(directory)); } directory = IOHelpers.NormalizeDirectory(directory); if (!Directory.Exists(directory)) { throw new DirectoryNotFoundException($"Source directory '{directory}' does not exist."); } IEnumerable <string> files; if (mixed) { files = InitialCacheBlockDirectories .Select(a => Path.Combine(directory, a)) .Where(Directory.Exists) .SelectMany(a => Directory.EnumerateFiles(a, "*", SearchOption.AllDirectories)) ; } else { if (Directory.EnumerateFiles(directory, "*").Any()) { throw new IOException($"Source directory '{directory}' has files in it. It should only contain directories."); } files = Directory.EnumerateFiles(directory, "*", SearchOption.AllDirectories); } return(files.Select(a => CacheBlockFileFileEntry.FromExternalName(a.Substring(directory.Length)))); }
public static Argument <IEnumerable <FileInfo> > ExistingOrWildcardOnly(this Argument <IEnumerable <FileInfo> > argument) { argument.AddValidator(symbol => symbol.Tokens .Select(t => t.Value) .Where(a => !IOHelpers.FileExistsOrWildcardDirectoryExists(a)) .Select(a => $"File does not exist: {a}") .FirstOrDefault() ); return(argument); }
public static ushort ZipVersion => 0x2D; //default to 4.5/ZIP64 even if it's not used /// <remarks> /// .NET Core version of <see cref="System.IO.Compression.ZipArchive"/> finally supports real store (0) method /// (instead of using deflate as .NET Framework does), although it's single-threaded. The problem is it's still /// unclear which files can be compressed, and which must be stored. /// </remarks> public static void CreatePak(string sourceDirectory, string pakLocation, IEnumerable <string> excludedDirectories = null, IEnumerable <KeyValuePair <string, string> > additionalFiles = null) { if (sourceDirectory is null) { throw new ArgumentNullException(nameof(sourceDirectory)); } if (pakLocation is null) { throw new ArgumentNullException(nameof(pakLocation)); } Console.WriteLine("Preparing ordered zip file..."); sourceDirectory = IOHelpers.NormalizeDirectory(sourceDirectory); if (!Directory.Exists(sourceDirectory)) { throw new IOException($"Source directory '{sourceDirectory}' does not exist."); } if (!File.Exists(Path.Combine(sourceDirectory, LoadListName))) { Console.WriteLine($"WARNING: {LoadListName} does not exist."); } using (var zipStream = File.Open(pakLocation, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read)) { Console.WriteLine($"Scanning: {sourceDirectory}"); var files = IOHelpers.GetRelativeAndFullNames(sourceDirectory, excludedDirectories) .Concat(additionalFiles ?? Enumerable.Empty <KeyValuePair <string, string> > ()) .OrderBy(a => a.Key, PakableFileNameComparer.Instance) //The list file must be the first file in the archive, stored without compression. .ToList() ; Console.Write("Storing files..."); using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create)) { var index = 0; foreach (var file in files) { Console.Write($"\rAdding file {index + 1}/{files.Count}"); var compress = CanBeCompressed(index, file.Key); zip.CreateEntryFromFile(file.Value, file.Key, compress ? CompressionLevel.Optimal : CompressionLevel.NoCompression); index++; } } } Console.WriteLine(); Console.WriteLine("Done."); }
/// <summary> /// Creates <see cref="DirectoryFilesContainer" />. /// </summary> public DirectoryFilesContainer(string location) : base(location) { NormalizedLocation = IOHelpers.NormalizeDirectory(location); }