2010-07-15 12 views
7

¿Cómo puedo "modificar" un InputStream? Tengo un archivo como entrada, me gustaría modificar algunas variables y reenviar un nuevo InputStream.Proceso InputStream

Por ejemplo, el InputStream inicial contiene Hola $ {var}. Entonces quiero "modificar" este InputStream con var = "world", lo que da como resultado un mundo Hello de InputStream.

Cuál es la mejor práctica para hacer esto? Gracias.

Respuesta

12

El java.io es uno y todo decorator pattern. Utilícela y cree una clase que extends InputStream (quizás DataInputStream o mejor, algunos Reader ya que en realidad le interesan los caracteres, no en bytes, pero ala), agregue un constructor que tome el InputStream original y anule los métodos read() para leer el flujo original en, búfer en cierto grado (por ejemplo, desde ${ hasta con firstnext }) y luego determinar la clave y devolver los datos modificados en su lugar.

Si llama a su nueva clase FormattedInputStream más o menos, entonces se podría volver a new FormattedInputStream(originalInputStream) el usuario final en su lugar y tener el usuario final sigue siendo sólo asignar y utilizarlo como un InputStream.

+0

1 - esta respuesta me hizo borrar mi propio texto inmediatamente. –

+0

Hola @BalusC ¿Su respuesta también es aplicable a los archivos de Excel? Me gustaría editar el inputstream y enviarlo al usuario. Aquí está mi mensaje: http://stackoverflow.com/questions/34893954/grails-edit-form-multipart-file-from-client-and-send-it-back-to-the-clien?noredirect=1#comment57594193_34893954 Gracias tú. – user3714598

3

Usted podría tratar de subclases FilterInputStream.

A partir de los documentos:

A FilterInputStream contiene algún otro flujo de entrada, que utiliza como su fuente básica de datos, posiblemente transformación de los datos en el camino o que proporcionan funcionalidades adicionales. La clase FilterInputStream simplemente reemplaza todos los métodos de InputStream con versiones que pasan todas las solicitudes a la corriente de entrada contenida. Las subclases de FilterInputStream pueden omitir algunos de estos métodos y también pueden proporcionar métodos y campos adicionales.

Aquí hay una puñalada inicial. No es la mejor manera de resolverlo. Es probable que desee anular algunos métodos más, y tal vez ir con un lector en su lugar. (O tal vez incluso utilizar un escáner y procesar el archivo línea por línea.)

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; 
     } 
    } 
} 

Salida:

Hello world, this is the value one 789 and this is the value two 123 
+0

Es exactamente por eso que sugerí 'DataInputStream' :) (que es una subclase). Aunque, después de todo, usar internamente un 'Reader' (' InputStreamReader') es más fácil. – BalusC

+0

Aha, no me di cuenta de que DataInputStream era un FilterInputStream. (Tiene sentido, sin embargo.) Entonces, ¿qué proporciona DataInputStream que FilterInputStream no (eso es útil en esta situación). – aioobe

2

usted podría utilizar Streamflyer que soporta las sustituciones de texto en caracteres corrientes fuera de la caja.

Cuestiones relacionadas