Question

Comment puis-je effectuer une recherche & amp; à la volée? remplacer dans un flux Java (entrée ou sortie)?

Je ne veux pas charger le flux en mémoire ou dans un fichier.

Je ne vois que les octets qui passaient et j'ai besoin de faire quelques remplacements. Les séquences remplacées sont courtes (jusqu’à 20 octets).

Était-ce utile?

La solution

Vous pouvez utiliser la classe fournie ici si les règles de remplacement statique vous suffisent.

Autres conseils

Vous pouvez implémenter un automate fini déterministe qui examine chaque octet une seule fois (par exemple, aucun lookbehind est obligatoire), de sorte que vous transmettriez essentiellement l’entrée via une mémoire tampon contenant autant de caractères que la longueur de votre modèle, en générant le modèle sur une correspondance ou des caractères débordants (non correspondants) lors de l’avancement du modèle. Le temps d’exécution est linéaire après la préparation du motif.

Wikipedia a quelques informations sur la la correspondance de modèles et son fonctionnement en théorie.

J'ai eu quelques bonnes idées grâce au lien fourni et j'ai fini par écrire une petite classe pour gérer le remplacement des variables $ VAR $ dans un flux. Pour la postérité:

public class ReplacingOutputStream extends OutputStream {
    private static final int DOLLAR_SIGN = "<*>quot;.codePointAt(0);
    private static final int BACKSLASH = "\\".codePointAt(0);
    private final OutputStream delegate;
    private final Map<String, Object> replacementValues;

    private int previous = Integer.MIN_VALUE;
    private boolean replacing = false;
    private ArrayList<Integer> replacement = new ArrayList<Integer>();


    public ReplacingOutputStream(OutputStream delegate, Map<String, Object> replacementValues) {
        this.delegate = delegate;
        this.replacementValues = replacementValues;
    }

    public @Override void write(int b) throws IOException {
        if (b == DOLLAR_SIGN && previous != BACKSLASH) {
            if (replacing) {
                doReplacement();
                replacing = false;
            } else {
                replacing = true;
            }
        } else {
            if (replacing) {
                replacement.add(b);
            } else {
                delegate.write(b);
            }
        }

        previous = b;
    }

    private void doReplacement() throws IOException {
        StringBuilder sb = new StringBuilder();
        for (Integer intval : replacement) {
            sb.append(Character.toChars(intval));
        }
        replacement.clear();

        String oldValue = sb.toString();
        Object _newValue = replacementValues.get(oldValue);
        if (_newValue == null) {
            throw new RuntimeException("Could not find replacement variable for value '"+oldValue+"'.");
        }

        String newValue = _newValue.toString();
        for (int i=0; i < newValue.length(); ++i) {
            int value = newValue.codePointAt(i);
            delegate.write(value);
        }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top