| File: Logging\BinaryLogger\Postprocessing\ArchiveFile.cs | Web Access |
| Project: src\msbuild\src\Build\Microsoft.Build.csproj (Microsoft.Build) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.IO; using System.IO.Compression; namespace Microsoft.Build.Logging { /// <summary> /// An object model for binlog embedded files. /// Used in <see cref="IBuildEventArgsReaderNotifications.ArchiveFileEncountered"/> event. /// </summary> public abstract class ArchiveData : IDisposable { private protected ArchiveData(string fullPath) => FullPath = fullPath; /// <summary> /// Full path of the original file before it was put in the embedded archive. /// </summary> public string FullPath { get; } /// <summary> /// Materializes the whole content of the embedded file in memory as a string. /// </summary> /// <returns></returns> public abstract ArchiveFile ToArchiveFile(); public virtual void Dispose() { } } /// <summary> /// Fully materialized (in-memory) embedded file. /// Easier to work with (the content is expressed in a single string), but more memory greedy. /// </summary> public sealed class ArchiveFile : ArchiveData { public ArchiveFile(string fullPath, string content) : base(fullPath) => Content = content; /// <summary> /// The content of the original file. /// </summary> public string Content { get; } /// <inheritdoc cref="ArchiveData.ToArchiveFile" /> public override ArchiveFile ToArchiveFile() => this; } /// <summary> /// Lazy (streaming) embedded file. /// Might be favorable for large files, as it doesn't materialize the whole content in memory. /// </summary> public sealed class ArchiveStream : ArchiveData { public ArchiveStream(string fullPath, StreamReader contentReader) : base(fullPath) => ContentReader = contentReader; /// <summary> /// Stream over the content of the archived file. /// </summary> public StreamReader ContentReader { get; } /// <summary> /// Creates an externally exposable embedded file representation from a <see cref="ZipArchiveEntry"/> (which is an implementation detail currently). /// </summary> /// <param name="entry"></param> /// <returns></returns> internal static ArchiveStream From(ZipArchiveEntry entry) { return new ArchiveStream(entry.FullName, new StreamReader(entry.Open())); } /// <inheritdoc cref="ArchiveData.ToArchiveFile" /> public override ArchiveFile ToArchiveFile() { var content = ContentReader.ReadToEnd(); ContentReader.Dispose(); return new ArchiveFile(FullPath, content); } public override void Dispose() => ContentReader.Dispose(); } }