コード例 #1
0
        /// <summary>
        /// Returns a list of all filenames in the remote .zip archive
        /// </summary>
        /// <param name="archiveUrl">URL of the .zip archive</param>
        /// <returns>List of filenames</returns>
        public static async Task <IEnumerable <string> > GetFileList(string archiveUrl)
        {
            PartialZipDownloader downloader = new PartialZipDownloader(archiveUrl);
            PartialZipInfo       info       = await downloader.Open();

            return(info.CentralDirectory.Select(cd => cd.FileName).OrderBy(f => f));
        }
コード例 #2
0
        private async Task <Tuple <byte[], DateTime> > Download(PartialZipInfo info, string filePath)
        {
            CentralDirectoryHeader cd = info.CentralDirectory.FirstOrDefault(c => c.FileName == filePath);
            DataProp dataProp;

            if (cd != null)
            {
                dataProp = cd.GetFileInfoStruct();

                byte[] localFileBuffer = await _httpService.GetRange(dataProp.headerOffset, dataProp.headerOffset + LocalFileHeader.Size - 1);

                LocalFileHeader localFileHeader = new LocalFileHeader(localFileBuffer);

                ulong  start             = dataProp.headerOffset + LocalFileHeader.Size + localFileHeader.FileNameLength + localFileHeader.ExtraFieldLength;
                byte[] compressedContent = await _httpService.GetRange(start, start + dataProp.compressedSize - 1);

                var dateTimeModified = ConvertDOSDateTime(dataProp.modifiedDate, dataProp.modifiedTime);

                switch (localFileHeader.Compression)
                {
                case 0:
                    return(Tuple.Create(compressedContent, dateTimeModified));

                case 8:
                    return(Tuple.Create(_deflateService.Inflate(compressedContent), dateTimeModified));

                default:
                    throw new PartialZipUnsupportedCompressionException("Unknown compression.");
                }
            }

            throw new PartialZipFileNotFoundException($"Could not find file in archive.");
        }
コード例 #3
0
        private async Task <byte[]> Download(PartialZipInfo info, string filePath)
        {
            CentralDirectoryHeader cd = info.CentralDirectory.FirstOrDefault(c => c.FileName == filePath);

            if (cd != null)
            {
                (ulong uncompressedSize, ulong compressedSize, ulong headerOffset, uint diskNum) = cd.GetFileInfo();

                byte[] localFileBuffer = await this._httpService.GetRange(headerOffset, headerOffset + LocalFileHeader.Size - 1);

                LocalFileHeader localFileHeader = new LocalFileHeader(localFileBuffer);

                ulong  start             = headerOffset + LocalFileHeader.Size + localFileHeader.FileNameLength + localFileHeader.ExtraFieldLength;
                byte[] compressedContent = await this._httpService.GetRange(start, start + compressedSize - 1);

                switch (localFileHeader.Compression)
                {
                case 0:
                    return(compressedContent);

                case 8:
                    return(this._deflateService.Inflate(compressedContent));

                default:
                    throw new PartialZipUnsupportedCompressionException("Unknown compression.");
                }
            }

            throw new PartialZipFileNotFoundException($"Could not find file {filePath} in archive.");
        }
コード例 #4
0
        /// <summary>
        /// Downloads a specific file from a remote .zip archive
        /// </summary>
        /// <param name="archiveUrl">URL of the .zip archive</param>
        /// <param name="filePath">Path of the file</param>
        /// <returns>File content</returns>
        public static async Task <byte[]> DownloadFile(string archiveUrl, string filePath)
        {
            PartialZipDownloader downloader = new PartialZipDownloader(archiveUrl);
            PartialZipInfo       info       = await downloader.Open();

            byte[] content = await downloader.Download(info, filePath);

            return(content);
        }
コード例 #5
0
        /// <summary>
        /// Downloads a specific file from a remote .zip archive
        /// </summary>
        /// <param name="archiveUrl">URL of the .zip archive</param>
        /// <param name="filePath">Path of the file in archive</param>
        /// <param name="writePath">Path where the file will be written</param>
        /// <param name="preserveTime">Preserve modification date</param>
        /// <returns>File content</returns>
        public static async Task DownloadFile(string archiveUrl, string filePath, string writePath)
        {
            PartialZipDownloader downloader = new PartialZipDownloader(archiveUrl);
            PartialZipInfo       info       = await downloader.Open();

            var content = await downloader.Download(info, filePath);

            File.WriteAllBytes(writePath, content.Item1);
            File.SetLastWriteTimeUtc(writePath, content.Item2);
        }
コード例 #6
0
        private async Task <PartialZipInfo> Open()
        {
            bool supportsPartialZip = await _httpService.SupportsPartialZip();

            if (!supportsPartialZip)
            {
                throw new PartialZipNotSupportedException("The web server does not support PartialZip as byte ranges are not accepted.");
            }

            PartialZipInfo info = new PartialZipInfo();

            info.Length = await _httpService.GetContentLength();

            byte[] eocdBuffer = await _httpService.GetRange(info.Length - EndOfCentralDirectory.Size, info.Length - 1);

            info.EndOfCentralDirectory = new EndOfCentralDirectory(eocdBuffer);

            ulong startCD, endCD;

            if (info.EndOfCentralDirectory.IsZip64)
            {
                byte[] eocdLocator64Buffer = await _httpService.GetRange(info.Length - EndOfCentralDirectory.Size - EndOfCentralDirectoryLocator64.Size, info.Length - EndOfCentralDirectory.Size);

                info.EndOfCentralDirectoryLocator64 = new EndOfCentralDirectoryLocator64(eocdLocator64Buffer);

                byte[] eocd64Buffer = await _httpService.GetRange(info.EndOfCentralDirectoryLocator64.EndOfCentralDirectory64StartOffset, info.EndOfCentralDirectoryLocator64.EndOfCentralDirectory64StartOffset + EndOfCentralDirectory64.Size - 1);

                info.EndOfCentralDirectory64 = new EndOfCentralDirectory64(eocd64Buffer);

                startCD = info.EndOfCentralDirectory64.CentralDirectoryStartOffset;
                endCD   = info.EndOfCentralDirectory64.CentralDirectoryStartOffset + info.EndOfCentralDirectory64.CentralDirectorySize + EndOfCentralDirectory64.Size - 1;
                info.CentralDirectoryEntries = info.EndOfCentralDirectory64.CentralDirectoryRecordCount;
            }
            else
            {
                startCD = info.EndOfCentralDirectory.CentralDirectoryStartOffset;
                endCD   = info.EndOfCentralDirectory.CentralDirectoryStartOffset + info.EndOfCentralDirectory.CentralDirectorySize + EndOfCentralDirectory.Size - 1;
                info.CentralDirectoryEntries = info.EndOfCentralDirectory.CentralDirectoryRecordCount;
            }

            byte[] cdBuffer = await _httpService.GetRange(startCD, endCD);

            info.CentralDirectory = CentralDirectoryHeader.GetFromBuffer(cdBuffer, info.CentralDirectoryEntries);

            return(info);
        }