Процесс InputStream - PullRequest
7 голосов
/ 15 июля 2010

Как я могу "изменить" InputStream? У меня есть файл для ввода, я хотел бы изменить некоторую переменную и переслать новый InputStream.

Например, начальный InputStream содержит Hello $ {var}. Затем я хочу "изменить" этот InputStream с помощью var = "world", получив в результате InputStream Hello world.

Какая лучшая практика для этого? Спасибо.

Ответы [ 3 ]

12 голосов
/ 15 июля 2010

java.io - это один и все шаблон декоратора .Воспользуйтесь им и создайте класс, который extends InputStream (может быть DataInputStream или лучше, немного Reader, поскольку вы на самом деле интересуетесь символами, а не байтами, ноala), добавить конструктор, который принимает исходный InputStream и переопределить методы read() для чтения исходного потока, буферизировать его в определенной степени (например, с ${ до firstnext }) и затем определитьвместо этого введите и верните измененные данные.

Если вы называете свой новый класс FormattedInputStream или около того, то вместо этого вы можете вернуть new FormattedInputStream(originalInputStream) конечному пользователю, а конечному пользователю все еще просто назначить и использовать его как InputStream.

4 голосов
/ 15 июля 2010

Вы можете попробовать создать подклассы FilterInputStream .

Из документов:

FilterInputStream содержит некоторый другой входной поток, который он использует какбазовый источник данных, возможно преобразование данных по пути или предоставление дополнительных функциональных возможностей.Сам класс FilterInputStream просто переопределяет все методы InputStream версиями, которые передают все запросы содержащемуся входному потоку.Подклассы FilterInputStream могут дополнительно переопределять некоторые из этих методов, а также могут предоставлять дополнительные методы и поля.

Вот начальный удар по нему.Не лучший способ решить это.Вы, вероятно, хотите переопределить еще несколько методов и, возможно, вместо этого использовать ридер.(Или, возможно, даже использовать сканер и обрабатывать файл построчно.)

import java.io.*;
import java.util.*;

public class Test {
    public static void main(String args[]) throws IOException {
        String str = "Hello world, this is the value one ${bar} and this " +
                     "is the value two ${foo}";

        // The "original" input stream could just as well be a FileInputStream.
        InputStream someInputStream = new StringBufferInputStream(str);

        InputStream modified = new SubstitutionStream(someInputStream);
        int c;
        while ((c = modified.read()) != -1)
            System.out.print((char) c);

        modified.close();
    }
}


class SubstitutionStream extends FilterInputStream {

    Map<String, String> valuation = new HashMap<String, String>() {{
        put("foo", "123");
        put("bar", "789");
    }};

    public SubstitutionStream(InputStream src) {
        super(src);
    }

    LinkedList<Character> buf = new LinkedList<Character>();

    public int read() throws IOException {

        if (!buf.isEmpty())
            return buf.remove();

        int c = super.read();

        if (c != '$')
            return c;

        int c2 = super.read();

        if (c2 == '{') {
            StringBuffer varId = new StringBuffer();
            while ((c2 = super.read()) != '}')
                varId.append((char) c2);

            for (char vc : valuation.get(varId.toString()).toCharArray())
                buf.add(vc);

            return buf.remove();

        } else {
            buf.add((char) c2);
            return c;
        }
    }
}

Вывод:

Hello world, this is the value one 789 and this is the value two 123
2 голосов
/ 29 июня 2012

Вы можете использовать Streamflyer , который поддерживает замену текста в символьных потоках из коробки.

...