Aspose.HTML для .NET 24.2.0 – сохранение HTML в поток

Aspose.HTML для .NET 24.2.0

В версии 24.2.0 интерфейс IOutputStorage объявлен устаревшим, но он будет продолжать работать до выхода версии 24.5.0. Если вы используете более ранние версии Aspose.HTML для .NET, мы рекомендуем вам обновиться и перейти на новую версию, поскольку версия 24.5.0 удалит этот устаревший интерфейс.

DeprecatedNew
IOutputStorage InterfaceResourceHandler Class

HTML-документ может содержать различные ресурсы, такие как CSS, внешние изображения и файлы. В статье мы рассмотрим случаи сохранения HTML-документов с ресурсами в Zip-архив и поток памяти. Aspose.HTML для .NET продолжает развивать и совершенствовать способы сохранения HTML-кодов со всеми связанными файлами. Здесь мы рассмотрим примеры сохранения файлов с использованием устаревших классов и предложим продвинутые решения по реализации новых классов.

Класс ResourceHandler против интерфейса IOutputStorage

Класс ResourceHandler позволяет разработчикам реализовать метод HandleResource(), в котором вы можете самостоятельно создать поток и выпустить его там, где вам это нужно. Новый метод добавляет возможность видеть Resource и обрабатывать дополнительную информацию о нем. Таким образом, приняв класс ResourceHandler, разработчики могут получить выгоду от более оптимизированного и выразительного подхода к управлению ресурсами, что приводит к более чистому, удобному в обслуживании и гибкому коду при сохранении HTML-документов.

Сохранить HTML в ZIP-архив

Здесь мы рассмотрим один и тот же пример сохранения файла with-resources.html в Zip-архив с использованием устаревшего интерфейса IOutputStorage и нового класса ResourceHandler.

Использование IOutputStorage – 24.1.0 и более ранние версии


Интерфейс IOutputStorage был базовым интерфейсом, который поддерживал создание потоков вывода и управление ими. Вы можете реализовать интерфейс IOutputStorage, создав класс ZipStorage для сохранения HTML с ресурсами в Zip-архив:

 1using System.IO;
 2using Aspose.Html;
 3using Aspose.Html.Saving;
 4using System.IO.Compression;
 5...
 6
 7	// Prepare a path to a source HTML file 
 8    string inputPath = Path.Combine(DataDir, "with-resources.html");;
 9    
10    var dir = Directory.GetCurrentDirectory();
11
12    // Prepare a full path to an output Zip storage
13    string customArchivePath = Path.Combine(dir, "./../../../../tests-out/old/archive.zip");
14
15    // Load the HTML document 
16    using (var doc = new HTMLDocument(inputPath))
17    {
18        // Initialize an instance of the ZipStorage class
19        using (var zipSrorage = new ZipStorage(customArchivePath))
20        {
21            // Save HTML with resources to a Zip archive
22            doc.Save(zipSrorage);
23        }
24    }

В следующем фрагменте кода показана реализация IOutputStorage в классе ZipStorage для демонстрации сохранения HTML-документа с ресурсами в Zip-архив:

 1    internal class ZipStorage : IOutputStorage, IDisposable
 2    {
 3        private FileStream zipStream;
 4        private ZipArchive archive;
 5        private int streamsCounter;
 6        private bool initialized;
 7
 8        public ZipStorage(string name)
 9        {
10            DisposeArchive();
11            zipStream = new FileStream(name, FileMode.Create);
12            archive = new ZipArchive(zipStream, ZipArchiveMode.Update);
13            initialized = false;
14        }
15
16        public OutputStream CreateStream(OutputStreamContext context)
17        {
18            var zipUri = (streamsCounter++ == 0 ? Path.GetFileName(context.Uri) :
19                Path.Combine(Path.GetFileName(Path.GetDirectoryName(context.Uri)), Path.GetFileName(context.Uri)));
20            var samplePrefix = String.Empty;
21            if (initialized)
22                samplePrefix = "my_";
23            else
24                initialized = true;
25
26            var newStream = archive.CreateEntry(samplePrefix + zipUri).Open();
27            var outputStream = new OutputStream(newStream, "file:///" + samplePrefix + zipUri);
28            return outputStream;
29        }
30
31        public void ReleaseStream(OutputStream stream)
32        {
33            stream.Flush();
34            stream.Close();
35        }
36
37        private void DisposeArchive()
38        {
39            if (archive != null)
40            {
41                archive.Dispose();
42                archive = null;
43            }
44            if (zipStream != null)
45            {
46                zipStream.Dispose();
47                zipStream = null;
48            }
49            streamsCounter = 0;
50        }
51
52        public void Dispose()
53        {
54            DisposeArchive();
55        }
56    }

Использование нового класса ResourceHandler – начиная с версии 24.2.0.


Класс ResourceHandler предназначен для реализации пользователями. В следующем примере C# показано, как сохранить документ HTML с ресурсами в Zip-архив с помощью класса ZipResourceHandler:

 1using System.IO;
 2using Aspose.Html;
 3using Aspose.Html.Saving;
 4using Aspose.Html.Saving.ResourceHandlers;
 5using System.IO.Compression;
 6...
 7
 8    // Prepare a path to a source HTML file 
 9    string inputPath = Path.Combine(DataDir, "with-resources.html");
10
11    var dir = Directory.GetCurrentDirectory();
12
13    // Prepare a full path to an output zip storage
14    string customArchivePath = Path.Combine(dir, "./../../../../tests-out/new/archive.zip");
15
16    // Load the HTML document
17    using (var doc = new HTMLDocument(inputPath))
18    {
19        // Initialize an instance of the ZipResourceHandler class
20        using (var resourceHandler = new ZipResourceHandler(customArchivePath))
21        {
22            // Save HTML with resources to a Zip archive
23            doc.Save(resourceHandler);
24        }
25    }

В следующем фрагменте кода показана реализация ResourceHandler в классе ZipResourceHandler для демонстрации сохранения HTML-документа с ресурсами в Zip-архив. Метод HandleResource() отвечает за обработку каждого ресурса в процессе сохранения при создании Zip-архива:

 1    internal class ZipResourceHandler : ResourceHandler, IDisposable
 2    {
 3        private FileStream zipStream;
 4        private ZipArchive archive;
 5        private int streamsCounter;
 6        private bool initialized;
 7
 8        public ZipResourceHandler(string name)
 9        {
10            DisposeArchive();
11            zipStream = new FileStream(name, FileMode.Create);
12            archive = new ZipArchive(zipStream, ZipArchiveMode.Update);
13            initialized = false;
14        }
15
16        public override void HandleResource(Resource resource, ResourceHandlingContext context)
17        {
18            var zipUri = (streamsCounter++ == 0
19                ? Path.GetFileName(resource.OriginalUrl.Href)
20                : Path.Combine(Path.GetFileName(Path.GetDirectoryName(resource.OriginalUrl.Href)),
21                    Path.GetFileName(resource.OriginalUrl.Href)));
22            var samplePrefix = String.Empty;
23            if (initialized)
24                samplePrefix = "my_";
25            else
26                initialized = true;
27
28            using (var newStream = archive.CreateEntry(samplePrefix + zipUri).Open())
29            {
30                resource.WithOutputUrl(new Url("file:///" + samplePrefix + zipUri)).Save(newStream, context);
31            }
32        }
33
34        private void DisposeArchive()
35        {
36            if (archive != null)
37            {
38                archive.Dispose();
39                archive = null;
40            }
41
42            if (zipStream != null)
43            {
44                zipStream.Dispose();
45                zipStream = null;
46            }
47
48            streamsCounter = 0;
49        }
50
51        public void Dispose()
52        {
53            DisposeArchive();
54        }
55    }

Сохранение HTML в потоки памяти

Давайте рассмотрим пример C# сохранения HTML-файла со связанными ресурсами в поток памяти с использованием устаревшего интерфейса IOutputStorage и нового класса ResourceHandler. Исходный документ with-resources.html и связанные с ним файлы находятся в одном каталоге.

Использование IOutputStorage – 24.1.0 и более ранние версии


Реализация интерфейса IOutputStorage позволяла сохранять HTML в потоки памяти:

 1using System.IO;
 2using Aspose.Html;
 3using Aspose.Html.Saving;
 4using System.Collections.Generic;
 5...
 6
 7    // Prepare a path to a source HTML file
 8    string inputPath = Path.Combine(DataDir, "with-resources.html");
 9
10    // Initialaze an HTML document
11    using (var doc = new HTMLDocument(inputPath))
12    {
13        // Create an instance of the MemoryOutputStorage class and save HTML to memory
14        var memoryStorage = new MemoryOutputStorage();
15        doc.Save(memoryStorage);
16	    memoryStorage.PrintInfo();
17    }

После запуска примера будет напечатано сообщение о хранении в памяти:

uri:memory:///with-resources.html, length:256
uri:memory:///photo1.png, length:57438

В следующем фрагменте кода показана реализация IOutputStorage в классе MemoryOutputStorage для демонстрации сохранения HTML-документа в потоках памяти:

 1    internal class MemoryOutputStorage : IOutputStorage
 2    {
 3        public List<Tuple<OutputStream, string>> Streams;
 4
 5        public MemoryOutputStorage()
 6        {
 7            Streams = new List<Tuple<OutputStream, string>>();
 8        }
 9
10        public OutputStream CreateStream(OutputStreamContext context)
11        {
12            var normalizedPath = new Url(context.Uri).Pathname;
13            var uri = new Url(Path.GetFileName(normalizedPath), "memory:///").Href;
14            var outputStream = new OutputStream(new MemoryStream(), uri);
15            Streams.Add(Tuple.Create(outputStream, uri));
16            return outputStream;
17        }
18
19        public void ReleaseStream(OutputStream stream)
20        {
21            stream.Flush();
22        }
23
24        public void PrintInfo()
25        {
26            foreach (var stream in Streams)
27                Console.WriteLine($"uri:{stream.Item2}, length:{stream.Item1.Length}");
28        }
29    }

Использование нового класса ResourceHandler – начиная с версии 24.2.0.


В следующем фрагменте кода показана реализация ResourceHandler в классе MemoryResourceHandler для демонстрации сохранения HTML-документа в потоках памяти:

 1using System.IO;
 2using Aspose.Html;
 3using Aspose.Html.Saving;
 4using Aspose.Html.Saving.ResourceHandlers;
 5using System.Collections.Generic;
 6...
 7
 8    // Prepare a path to a source HTML file 
 9    string inputPath = Path.Combine(DataDir, "with-resources.html");
10    
11    // Load the HTML document
12    using (var doc = new HTMLDocument(inputPath))
13    {
14        // Create an instance of the MemoryResourceHandler class and save HTML to memory
15        var resourceHandler = new MemoryResourceHandler();
16        doc.Save(resourceHandler);
17        resourceHandler.PrintInfo();
18    }

Вместо методов CreateStream() и ReleaseStream(), реализованных в классе MemoryOutputStorage интерфейса IOutputStorage, теперь существует один метод HandleResource(), реализованный в классе MemoryResourceHandler интерфейса ResourceHandler, в котором вы можете сами создать поток и выпустить его туда, где вам это нужно. Новый метод добавляет возможность видеть Resource и обрабатывать дополнительную информацию о нем:

 1    internal class MemoryResourceHandler : ResourceHandler
 2    {
 3        public List<Tuple<Stream, Resource>> Streams;
 4
 5        public MemoryResourceHandler()
 6        {
 7            Streams = new List<Tuple<Stream, Resource>>();
 8        }
 9
10        public override void HandleResource(Resource resource, ResourceHandlingContext context)
11        {
12            var outputStream = new MemoryStream();
13            Streams.Add(Tuple.Create<Stream, Resource>(outputStream, resource));
14            resource
15                .WithOutputUrl(new Url(Path.GetFileName(resource.OriginalUrl.Pathname), "memory:///"))
16                .Save(outputStream, context);
17        }
18
19        public void PrintInfo()
20        {
21            foreach (var stream in Streams)
22                Console.WriteLine($"uri:{stream.Item2.OutputUrl}, length:{stream.Item1.Length}");
23        }
24    }

Как видите, новый подход напрямую работает с объектами Resource, устраняя необходимость в дополнительных классах, таких как OutputStream. Это упрощает код и делает взаимодействие с ресурсами более явным и понятным. Таким образом, базовый класс ResourceHandler предлагает более упрощенный и выразительный способ обработки ресурсов при сохранении HTML-документов в потоки памяти.

После запуска примера будет напечатано сообщение о хранении в памяти:

uri:memory:///with-resources.html, length:256
uri:memory:///photo1.png, length:57438

Aspose.HTML предлагает бесплатные Веб-приложения HTML, которые представляют собой онлайн-коллекцию бесплатных конвертеров, слияний, инструментов SEO, генераторов HTML-кода, инструментов URL и многого другого. Приложения работают в любой операционной системе с веб-браузером и не требуют установки дополнительного программного обеспечения. Это быстрый и простой способ эффективно и результативно решить ваши задачи, связанные с HTML документами.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.