Как я могу "изменить" InputStream? У меня есть файл, как введено, я хотел бы изменить некоторую переменную и передать новый InputStream.
Например, начальный InputStream содержит Привет $ {var}. Затем я хочу "изменить" этот InputStream с var = "мир", заканчиваясь InputStream Привет мир.
Что лучшая практика должна сделать это?Спасибо.
Шаблон java.io
является одним и всех декораторов. Воспользуйтесь им и создайте класс, который расширяет InputStream
(может быть DataInputStream
или, лучше, какой-нибудь Reader
поскольку вас на самом деле интересуют символы, а не байты, аля), добавьте конструктор, который принимает исходный InputStream
и переопределите методы read()
для чтения исходного потока, буферизации его до определенной степени (e. например, от ${
до firstnext }
), а затем определить ключ и вернуть измененные данные.
Если вы назовете свой новый класс FormattedInputStream
или так, то вместо этого вы можете вернуть new FormattedInputStream(originalInputStream)
конечному пользователю, и конечный пользователь по-прежнему будет просто назначать и использовать его как InputStream
.
Вы можете попробовать создать подкласс 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