2010-07-15 2 views
7

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

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

Какова наилучшая практика для этого? Благодарю.

ответ

12

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

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

+0

+1 - этот ответ заставил меня немедленно удалить свой текст. –

+0

Привет @BalusC Является ли ваш ответ применимым к файлам Excel? Я бы хотел отредактировать входной поток и отправить его пользователю. Вот мой пост: http://stackoverflow.com/questions/34893954/grails-edit-form-multipart-file-from-client-and-send-it-back-to-the-clien?noredirect1_comment57594193_34893954 Спасибо вы. – user3714598

3

Вы можете попробовать подклассы 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 
+0

Именно поэтому я предложил 'DataInputStream' :) (который является его подклассом). Хотя, в конце концов, внутренне использовать 'Reader' (' InputStreamReader') проще. – BalusC

+0

Ага, я не понимал, что DataInputStream был FilterInputStream. (Имеет смысл, хотя.) Итак, что DataInputStream обеспечивает, что FilterInputStream не делает (это полезно в этой ситуации.) – aioobe

2

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

Смежные вопросы