Nano Hash - криптовалюты, майнинг, программирование

Обработка потока в пользовательском преобразователе URI для Saxon Parser

Мне нужно обработать xml против xslt с результирующим документом, который создает много xml. Как предлагается здесь: Поймать выходной поток документа-результата xsl

Я написал свой личный преобразователь URI:

public class CustomOutputURIResolver implements OutputURIResolver{

    private File directoryOut;

    public CustomOutputURIResolver(File directoryOut) {
        super();
        this.directoryOut = directoryOut;
    }

    public void close(Result arg0) throws TransformerException {

    }

    public Result resolve(String href, String base) throws TransformerException {
       FileOutputStream fout = null;
       try {
            File f = new File(directoryOut.getAbsolutePath() + File.separator + href + File.separator + href + ".xml");
            f.getParentFile().mkdirs();
            fout = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return new StreamResult(fout);
    }

}

который получает выходной каталог, а затем сохраняет здесь файлы.

Но затем, когда я тестировал его в junit, у меня были некоторые проблемы на этапе очистки, когда я пытался удалить созданные файлы и заметил, что поток FileOutputStream плохо обрабатывается. Попытка решить проблему натолкнула меня на некоторые мысли:

Сначала я пришел к этой идее:

public class CustomOutputURIResolver implements OutputURIResolver{

    private File directoryOut;
    private FileOutputStream fout

    public CustomOutputURIResolver(File directoryOut) {
        super();
        this.directoryOut = directoryOut;
        this.fout = null;
    }

    public void close(Result arg0) throws TransformerException {
        try {
            if (null != fout) {
                fout.flush();
                fout.close();
                fout = null;
            }
        } catch (Exception e) {}
    }

    public Result resolve(String href, String base) throws TransformerException {

        try {
            if (null != fout) {
                fout.flush();
                fout.close();
            }
        } catch (Exception e) {}

        fout = null;
        try {
            File f = new File(directoryOut.getAbsolutePath() + File.separator + href + File.separator + href + ".xml");
        f.getParentFile().mkdirs();
            fout = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return new StreamResult(fout);
    }

}

Таким образом, fileOutputStream закрывается каждый раз, когда открывается другой. Но:

1) мне не очень нравится это решение

2) что делать, если эта функция вызывается в многопоточном процессе? (Я не очень хорошо разбираюсь в саксонском разборе, поэтому я действительно не знаю..)

3) Есть ли возможность создать и обработать один FileOutputStream для каждого разрешения?


Ответы:


1

Причина, по которой close() принимает аргумент Result, заключается в том, что вы можете определить, какой поток нужно закрыть. Почему нет:

public void close(Result arg0) throws TransformerException {
    try {
        if (arg0 instanceof StreamResult) {
            OutputStream os = ((StreamResult)arg0).getOutputStream();
            os.flush();
            os.close();
        }
    } catch (Exception e) {}
}

Начиная с Saxon-EE 9.5, xsl:result-document выполняется в новом потоке, поэтому очень важно, чтобы OutputURIResolver был потокобезопасным. Из-за этого изменения, начиная с версии 9.5, OutputURIResolver должен реализовывать дополнительный метод getInstance(), упрощающий управление состоянием: если ваш метод newInstance() действительно создает новый экземпляр, то для каждого результирующего документа будет один экземпляр OutputURIResolver. обрабатывается, и он может удерживать поток вывода и закрывать его по запросу.

08.01.2014
  • все верно.. я почему-то думал, что функция закрытия вызывается только в конце всего процесса и не обратил внимания на ее аргумент.. теперь я упорядочил код и все заработало, спасибо! 09.01.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..