Inputstream a partir de uma string?

8 respostas
F

boas!
eu preciso de criar uma InputStream que receba dados desde uma String.
Já fiz isto:

String myString="ola"; public InputStream is = new ByteArrayInputStream(myString.getBytes()); Scanner teclado = new Scanner(is); PrintStream saida = new PrintStream(socket.getOutputStream()); // socket é um Socket que se liga a outro computador. while (teclado.hasNextLine()) { saida.println(name+": "+teclado.nextLine()); }

A primeira vez lê muito bem, mas quando eu altero a String ( myString=“qualquer coisa nova”; ), o scanner não reconhece que houve qualquer mudança e se eu fizer:
System.out.println(is.read()); retorna -1, o que significa que não houve qualquer mudanças reconhecidas pela inputstream.

Como é que se resolve isto? ou como é que se faz para ter uma InputStream que não seja o System.in nem uma stream que leia de um arquivo, mas que a partir de uma String consiga ler dados e envia-los quando a string é modificada?

Muito Obrigado desde já. Se for precisa mais alguma informação é só dizer.
Francisco

8 Respostas

nel

Oi!

Franciso, String é um objeto imutavél! Portanto, terás de realizar o mesmo esforço sempre que executar uma alteração na String.
Podes deixar o método receber a String como parametro, dessa forma, toda vez que tiver um valor novo da String envia ao método que realiza o envio conforme sua necessidade.

Abraços.

F

Está a dizer isto?

String myString="ola"; Scanner teclado = new Scanner(myString); PrintStream saida = new PrintStream(socket.getOutputStream()); // socket é um Socket que se liga a outro computador. while (teclado.hasNextLine()) { saida.println(name+": "+teclado.nextLine()); }

Continua a não dar :frowning:

Isso da String ser imutável nunca percebi muito bem. Se eu tenho String myString=“ola”; e depois faço: myString=“adeus”; não a estou a mudar?

Obrigado

nel

Não, não era isso.
Era criação de um método separada com parametros, inclusive a String, para que possa fazer uso do contéudo dela.

Não estou compreendendo o que você precisa.
Esqueça o Java e nos conte exatamente sua necessidade, creio que fica mais fácil ajuda-lo.

Abraços.

F

franciscobc:
Está a dizer isto?

String myString="ola"; Scanner teclado = new Scanner(myString); PrintStream saida = new PrintStream(socket.getOutputStream()); // socket é um Socket que se liga a outro computador. while (teclado.hasNextLine()) { saida.println(name+": "+teclado.nextLine()); }

Continua a não dar :frowning:

Isso da String ser imutável nunca percebi muito bem. Se eu tenho String myString=“ola”; e depois faço: myString=“adeus”; não a estou a mudar?

Obrigado

Quando você declara String myString = “ola” e depois faz myString = “adeus”, você está, implicitamente, criando uma nova instância da string e inicializando ela com “adeus”. A instância anterior, por não ter nenhum objeto apontando mais para ela, vai ser recolhida pelo garbage colector. E acontece a mesma coisa se você canconetar duas ou mais strings. Daí, quando você quiser uma string que vai mudar toda hora, você usar StringBuffer.

F

fernando.camargo:

Daí, quando você quiser uma string que vai mudar toda hora, você usar StringBuffer.

Eu usei um StringBuffer e o resultado continua a ser o mesmo:
imprime o que está na stringbuffer ao principio mas depois, quando eu altero o stringbuffer, nao imprime nada.

StringBuffer myString=new StringBuffer ("ola"); Scanner teclado = new Scanner(myString.toString()); PrintStream saida = new PrintStream(socket.getOutputStream()); // socket é um Socket que se liga a outro computador. while (teclado.hasNextLine()) { saida.println(name+": "+teclado.nextLine()); } myString.append("adeus"); // neste caso não estou a alterar, mas sim a concatenar mas ainda assim, não imprime.

Será que o problema está no while loop e na verificação do scanner hasNextLine() ? Não da para “mostrar” ao scanner que sim, que há uma nova linha? Eu tentei com .next(“adeus”); mas não deu, deu um erro de NoSuchElementException porque pelos vistos a string dentro do parametro tinha de ser um pattern mas o que é um pattern?
não encontro mais informação do que isto e isto não é esclarecedor:
http://download.oracle.com/javase/1,5.0/docs/api/java/util/Scanner.html ( desça ate .next(String pattern) )

nel

Oi!

Francisco, se você invoca o método append do StringBuffer significa que quer concatenar um valor aos que já possam existir. Se queres “zerar”, simplesmente crie outra instancia do StringBuffer e use o append.

Eu, até o momento, não entendi ainda o que você precisa.
Pois o seu tópico diz que é para criar um InputStream de uma String e isso, esse código resolve:

byte[] input = new String("testando uma String").getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(input);

Agora, se você precisa mais do que isso, poste o seu código completo e principalmente, o que você quer!
Porque até agora, no meu ponto de vista, você não foi claro na sua necessidade!

Abraços.

F

Ok, para começar quero pedir desculpas porque pensava que tinha sido mais ou menos claro. As vossas respostas me ajudaram a perceber que aquilo que eu estava à procura era de outra coisa diferente daquilo que perguntei. Por isso aqui vai a minha pergunta realmente: ( se acharem que eu deveria por isto noutro tópico, digam )
Eu tenho um programa que tem uma JTeaxtArea, que, quando é mudada, o seu novo valor é guardado numa String. E depois tenho uma conexão a outro pc e quero mandar o valor dessa String para o outro pc sempre que essa String tem um novo valor ( que vem da textArea ):

public void Connect()
{
try {
Socket cliente = new Socket("192.168.2.104", 12346);
PrintStream saida = new PrintStream(cliente.getOutputStream());
saida.println(myString);  // imaginemos que myString já estava inicializada
 }
catch (UnknownHostException e1){
         e1.printStackTrace();
 }
catch (IOException e1) {
         e1.printStackTrace();
 }
}

public void keyPressed(KeyEvent e)     
    {   		
    	int keyCode = e.getKeyCode();                                // Todo este método faz com que, quando o enter é pressionado, todo o conteudo da 
    	if (keyCode==10)                                                   // JTextArea seja gravado em myString
    		myString=writeArea.getText();			
    }

Agora eu não faço a mínima ideia como resolver este problema visto que ao usar Buffers / Scanners / Streams em todo o lado, nunca funciona porque das duas, uma:

  1. ou so imprime o valor inicial da String e nunca mais imprime nada quando a String é mudada
    2) ou não funciona porque está fora da scope da [color=red]PrintStream[/color]

Inclusive tentei iniciando um thread do metodo Connect ( que nesse caso implementaria a classe Runnable ).

Se não fui claro, por favor digam porque eu já estou com este problema há uns dias e já tentei de tudo e só quero é resolve-lo!
Obrigado!

nel

Oi!

Agora você foi absolutamente muito mais claro!
Ou você cria um botão do tipo "enviar" ou decide um evento a tratar do seu JTextArea, como quando perde o "foco".
Somente digitando não rola, pois imagina, você digita uma letra e ele já envia, então, o ideal é confirmar que o usuário terminou.
Recomendo um botão, creio que seja tranquilo, mas isso é decisão sua.

Pega o seu método de conexão e faça-o receber uma String. Essa String será exatamente o valor que consta no seu JTextArea.
Quando tratares o evento, faça com que ele invoke o seu método, enviando todo o texto digitado, dessa forma, sua String sempre será atualizada.

Se queres manter o padrão que já tem, substitua sua String por uma StringBuffer e após usa-la, crie uma nova instância.
Algo assim, veja se clarea:

public void Connect()   
private StringBuffer sb = new StringBuffer();
{   
try {   
Socket cliente = new Socket("192.168.2.104", 12346);   
PrintStream saida = new PrintStream(cliente.getOutputStream());   
saida.println(sb.toString());
sb = new StringBuffer();  // imaginemos que myString já estava inicializada   
}   
catch (UnknownHostException e1){   
         e1.printStackTrace();   
}   
catch (IOException e1) {   
         e1.printStackTrace();   
}   
}   
  
public void keyPressed(KeyEvent e)       
    {             
        int keyCode = e.getKeyCode();                                // Todo este método faz com que, quando o enter é pressionado, todo o conteudo da   
        if (keyCode==10)                                                   // JTextArea seja gravado em myString   
            sb.append(writeArea.getText());             
    }  
}

Eu não olhei o seu método de conexão com Socket. Eu simplesmente quis dar uma idéia de como pode fazer para capturar a String!
Abraços.

Criado 1 de setembro de 2011
Ultima resposta 8 de set. de 2011
Respostas 8
Participantes 3