Redireccionar un string a System.in

Thanat0s

Buenas, alguien me podría echar una mano diciéndome si conoce alguna manera de redireccionar un string a System.in

También me serviría un buffer o cualquier cosa que pudiera volcar usando System.setIn

Llevo cerca de 2 horas dándole vueltas a esto, buscando con google y no encuentro una mierda... y dado a que mis profesores no me han dado ningún tipo de apunte me tengo que buscar la vida como bien pueda.

He estado mirando la documentación de InputStream una y otra vez, porque lo que necesito es alguna clase hija de tipo InputStream que pueda actualizar/modificar en tiempo de ejecución.

Tengo este código pero no funciona:

StringBufferInputStream aux=new StringBufferInputStream("go north");
System.setIn(aux);
try {
	aux.read(ae.getActionCommand().getBytes());
} catch (IOException e1) {
	// TODO Auto-generated catch block
	e1.printStackTrace();
}

pd: la idea es que antes tenía una aventura conversacional que funcionaba escribiendo comandos en consola, como por ejemplo "go north", pero ahora estamos metiendo parte gráfica con botones que tienen que hacer la misma función que los comandos antiguos y a la vez respetando la estructura lógica que teníamos hecha, es decir, no puedo modificar la parte lógica del juego que tenía hecha y por tanto necesito que cuando pulse un botón se genere en texto un comando y que este se lo pase a la parte lógica.

NeB1

No sé si esto te ayudará

package pruebasystemin;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.io.*;

/**
 *
 * @author Jordi
 */
public class Main {
    public static void main(String[] args) {
        BufferedInputStream in = new BufferedInputStream(new StringBufferInputStream("1234567890"));

System.setIn(in);
try
{
    byte[] b = new byte[10];
    System.in.read(b);
    for(int i = 0; i < 10; i++)
    {
        System.out.println(b[i]);
    }
}
catch(Exception exc)
{
}
    }

}

Así le he metido a system in, la cadena 1234567890 y después la he leído (en bytes). La ejecución del código devuelve

49
50
51
52
53
54
55
56
57
48

Es decir, la representación ASCII de cada número.

1 respuesta
LOc0

Por partes. Imagino #1 que lanzarás un thread con la "lógica" que lee de System.in y otro thread con la GUI de los botones. El "problema" de hacer lo que propone NeB1 es que el método read() de StringBufferInputStream (que además está deprecated) NO ES BLOQUEANTE. ¿Qué pasa entonces? Pues que la primera vez que leas irá bien, pero en las siguientes System.in.read devolverá -1 inmediatamente (en vez de quedarse esperando como haría si leyera del System.in del teclado). He estado trasteando porque este tema me parecía interesante y hacía bastante que no tocaba Java. Te pongo una posible solución:

import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class Main {
	
public static void main(String args[])
{
	try
	{
		PipedInputStream ps=new PipedInputStream();
		System.setIn(ps);
		
		Escritor escritor=new Escritor(new PipedOutputStream(ps), 2);
		escritor.start();
		
		int c;
		
		while((c=System.in.read())!=-1)
			System.out.print((char)c);
	}
	catch(Exception e)
	{
		e.printStackTrace();
	}
}
}
import java.io.OutputStream;


public class Escritor extends Thread {
	
public int timeout;
public OutputStream salida;

public Escritor(OutputStream salida, int timeout)
{
	this.salida=salida;
	this.timeout=timeout;
}

public void run()
{
	while(true)
	{
		try
		{
			this.salida.write("Escritor escribe hola\n".getBytes());
			Thread.sleep(this.timeout*1000);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}			
	}
}
}

La idea es utilizar una tubería que SÍ BLOQUEA. En el código de ejemplo se crea un hilo escritor que cada dos segundos "teclea" un mensaje que el hilo principal lee de System.in En tu caso, en vez del thread escritor será el thread de la GUI (o uno de ellos) el que escriba en la tubería el comando en cuestión.

Salu2 ;)

1 respuesta
Thanat0s

Aunque no contesté ayer os leí y me fui a clase teórica dispuesto a preguntar al profesor a ver si él sugería algo...

Total que llego, le pregunto y se quedó flipando, al final dice algo diferente de lo que digo la otra vez en clase y no tenemos que ejecutar por completo la parte lógica antigua bajo la gráfica, pero sí que podemos usar parte.

Así que no voy a necesitar redirigir nada al System.in, aún así lo probaré esta noche.

#2 algo muy parecido probé y como dice #3 se queda pillado después de leer la primera línea.

Saludos y gracias a ambos.

pd: el profesor debe de leerse por encima el guión y nos cuenta lo que le da la gana en cada clase...

Usuarios habituales

  • Thanat0s
  • LOc0
  • NeB1