File: System\IO\Compression\ZipFileExtensions.ZipArchive.Create.Async.cs
Web Access
Project: src\src\libraries\System.IO.Compression.ZipFile\src\System.IO.Compression.ZipFile.csproj (System.IO.Compression.ZipFile)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Threading;
using System.Threading.Tasks;
 
namespace System.IO.Compression;
 
public static partial class ZipFileExtensions
{
    /// <summary>
    /// <p>Asynchronously adds a file from the file system to the archive under the specified entry name.
    /// The new entry in the archive will contain the contents of the file.
    /// The last write time of the archive entry is set to the last write time of the file on the file system.
    /// If an entry with the specified name already exists in the archive, a second entry will be created that has an identical name.
    /// If the specified source file has an invalid last modified time, the first datetime representable in the Zip timestamp format
    /// (midnight on January 1, 1980) will be used.</p>
    ///
    /// <p>If an entry with the specified name already exists in the archive, a second entry will be created that has an identical name.</p>
    ///
    /// <p>Since no <code>CompressionLevel</code> is specified, the default provided by the implementation of the underlying compression
    /// algorithm will be used; the <code>ZipArchive</code> will not impose its own default.
    /// (Currently, the underlying compression algorithm is provided by the <code>System.IO.Compression.DeflateStream</code> class.)</p>
    /// </summary>
    ///
    /// <exception cref="ArgumentException">sourceFileName is a zero-length string, contains only whitespace, or contains one or more
    /// invalid characters as defined by InvalidPathChars. -or- entryName is a zero-length string.</exception>
    /// <exception cref="ArgumentNullException">sourceFileName or entryName is null.</exception>
    /// <exception cref="PathTooLongException">In sourceFileName, the specified path, file name, or both exceed the system-defined maximum length.
    /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.</exception>
    /// <exception cref="DirectoryNotFoundException">The specified sourceFileName is invalid, (for example, it is on an unmapped drive).</exception>
    /// <exception cref="IOException">An I/O error occurred while opening the file specified by sourceFileName.</exception>
    /// <exception cref="UnauthorizedAccessException">sourceFileName specified a directory. -or- The caller does not have the
    /// required permission.</exception>
    /// <exception cref="FileNotFoundException">The file specified in sourceFileName was not found. </exception>
    /// <exception cref="NotSupportedException">sourceFileName is in an invalid format or the ZipArchive does not support writing.</exception>
    /// <exception cref="ObjectDisposedException">The ZipArchive has already been closed.</exception>
    /// <exception cref="OperationCanceledException">An asynchronous operation is cancelled.</exception>
    ///
    /// <param name="destination">The zip archive to add the file to.</param>
    /// <param name="sourceFileName">The path to the file on the file system to be copied from. The path is permitted to specify
    /// relative or absolute path information. Relative path information is interpreted as relative to the current working directory.</param>
    /// <param name="entryName">The name of the entry to be created.</param>
    /// <param name="cancellationToken">The cancellation token to monitor for cancellation requests.</param>
    /// <returns>A wrapper for the newly created entry.</returns>
    public static Task<ZipArchiveEntry> CreateEntryFromFileAsync(this ZipArchive destination, string sourceFileName, string entryName, CancellationToken cancellationToken = default) =>
        DoCreateEntryFromFileAsync(destination, sourceFileName, entryName, null, cancellationToken);
 
    /// <summary>
    /// <p>Asynchronously adds a file from the file system to the archive under the specified entry name.
    /// The new entry in the archive will contain the contents of the file.
    /// The last write time of the archive entry is set to the last write time of the file on the file system.
    /// If an entry with the specified name already exists in the archive, a second entry will be created that has an identical name.
    /// If the specified source file has an invalid last modified time, the first datetime representable in the Zip timestamp format
    /// (midnight on January 1, 1980) will be used.</p>
    /// <p>If an entry with the specified name already exists in the archive, a second entry will be created that has an identical name.</p>
    /// </summary>
    /// <exception cref="ArgumentException">sourceFileName is a zero-length string, contains only whitespace, or contains one or more
    /// invalid characters as defined by InvalidPathChars. -or- entryName is a zero-length string.</exception>
    /// <exception cref="ArgumentNullException">sourceFileName or entryName is null.</exception>
    /// <exception cref="PathTooLongException">In sourceFileName, the specified path, file name, or both exceed the system-defined maximum length.
    /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.</exception>
    /// <exception cref="DirectoryNotFoundException">The specified sourceFileName is invalid, (for example, it is on an unmapped drive).</exception>
    /// <exception cref="IOException">An I/O error occurred while opening the file specified by sourceFileName.</exception>
    /// <exception cref="UnauthorizedAccessException">sourceFileName specified a directory.
    /// -or- The caller does not have the required permission.</exception>
    /// <exception cref="FileNotFoundException">The file specified in sourceFileName was not found. </exception>
    /// <exception cref="NotSupportedException">sourceFileName is in an invalid format or the ZipArchive does not support writing.</exception>
    /// <exception cref="ObjectDisposedException">The ZipArchive has already been closed.</exception>
    /// <exception cref="OperationCanceledException">An asynchronous operation is cancelled.</exception>
    ///
    /// <param name="destination">The zip archive to add the file to.</param>
    /// <param name="sourceFileName">The path to the file on the file system to be copied from. The path is permitted to specify relative
    /// or absolute path information. Relative path information is interpreted as relative to the current working directory.</param>
    /// <param name="entryName">The name of the entry to be created.</param>
    /// <param name="compressionLevel">The level of the compression (speed/memory vs. compressed size trade-off).</param>
    /// <param name="cancellationToken">The cancellation token to monitor for cancellation requests.</param>
    /// <returns>A wrapper for the newly created entry.</returns>
    public static Task<ZipArchiveEntry> CreateEntryFromFileAsync(this ZipArchive destination,
                                                      string sourceFileName, string entryName, CompressionLevel compressionLevel, CancellationToken cancellationToken = default) =>
        DoCreateEntryFromFileAsync(destination, sourceFileName, entryName, compressionLevel, cancellationToken);
 
    internal static async Task<ZipArchiveEntry> DoCreateEntryFromFileAsync(this ZipArchive destination, string sourceFileName, string entryName,
                                                    CompressionLevel? compressionLevel, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();
 
        (FileStream fs, ZipArchiveEntry entry) = InitializeDoCreateEntryFromFile(destination, sourceFileName, entryName, compressionLevel, useAsync: true);
 
        await using (fs)
        {
            Stream es = await entry.OpenAsync(cancellationToken).ConfigureAwait(false);
            await using (es)
            {
                await fs.CopyToAsync(es, cancellationToken).ConfigureAwait(false);
            }
        }
 
        return entry;
    }
 
}