Komunikacja między wątkiami - PipedReader, PipedWriter odebranie i wysłanie stringa

0

Mam problem - o ile wysłanie liczby całkowitej nie sprawia problemów, o tyle wysłanie double czy float już tak. Pomyślałem, żeby zamienić liczbę na string i wysłać je w takiej postaci - tu chyba jest ok. Problem pojawia się jednak przy odbiorze. Skąd mogę wiedzieć, ile bajtów mam odebrać? Nie ma możliwości odbioru stringa, a bufor trzebaby zainicjalizować. Szukałem w necie, ale nic takigo nie znalazłem. Mój problem: jak przesłać i odebrać za pomocą PipedReader, PipedWriter liczbę float/double albo string ? Oto kod:

import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.util.Random;

class wyslij extends Thread{

    private PipedWriter pw;

    public wyslij(PipedReader pr){
            try {
                this.pw = new PipedWriter(pr);
            } catch (IOException ex) {}
    }

    @Override
    public void run(){
        try{

           double liczba = 0;
           Random rand = new Random();
           liczba = rand.nextDouble();

            String temp = "";
            temp += liczba;

            System.out.println("Wyslano: "+temp);

            pw.write(temp);

        } catch (IOException ex) {System.out.println(ex.getMessage());}
    }

}

class odbierz extends Thread{

    private wyslij s;
    private PipedReader pis;

    public odbierz(){
        this.pis = new PipedReader();
        this.s = new wyslij(pis);

    }

    @Override
    public void run(){

            double odebrana = 0;

        try {

            s.start();
            while (!pis.ready()) {}

        } catch (IOException ex) {}

        System.out.println("Odebrano: "+odebrana);

    }
}

public class Main {

    public static void main(String[] args) {
        odbierz m = new odbierz();
        m.start();
    }
}
0

Oto kod rozbijający double na inty:

public class Main {

    public static void main(String[] args) {
        final double E = Math.E;
        long bits = Double.doubleToRawLongBits(E);
        System.out.printf("%x %x\n", bits >> 32, bits & ((1l << 32) - 1));
    }
}

Jeśli chcesz wysłać napis to najlepiej najpierw wyślij inta mówiącego o długości napisu, a potem napis bez znaku kończącego. Ewentualnie wyślij napis ze znakiem kończącym (zwykle "\0"), a potem wczytuj znaki (np do StringBuildera), aż napotkasz znak kończący.

PipedReader możesz chyba zapakować w BufferedReader, a PipedWriter zapakować w PrintWriter/ BufferedWriter, a potem wysyłać i odbierać wszystko jako Stringi. Jednak konwersja z/ na String nie dość że czasochłonna, to jeszcze zabiera dodatkową pamięć.

Edit:
Chociaż w dokumentacji PrintWritera jest napisane:

Piped character-output streams.

Czyli wynika z tego, że Piped<Reader/ Writer> operują na charach, a więc bezpieczniej byłoby posługiwać się reprezentacją Stringową.

W każdym razie do komunikacji między-wątkowej istnieją lepsze/ elastyczniejsze rozwiązania. Potoki generalnie służą do komunikacji międzyprocesowej.

0

Dzięki, ale dla mnie to trochę zbyt skomplikowane rozwiązanie ;) Pomogło mi coś takiego : http://www.java2s.com/Code/JavaAPI/java.io/newPipedWriter.htm (chociaż nie ukrywam, że składanie stringa z charów trwa dość długo ...)

0

Czy możesz zamiast PipedWriter / PipedReader użyć PipedOutputStream / PipedInputStream?
Wtedy możesz opakować to w DataStreamy:

DataOutputStream dataOut = new DataOutputStream(pipedOut);
dataOut.writeDouble(1.23);
dataOut.writeUTF("1.23");

DataInputStream dataIn = new DataInputStream(pipedIn);
dataIn.readDouble();
dataIn.readUTF();
0

Tak się szczesliwie składa, że mogę :) i spróbuję z Twoim rozwiązaniem, bo przy moim to dalej jest źle -.- (chodzi mi o czytanie, bo pisanie bez problemu)

1 użytkowników online, w tym zalogowanych: 0, gości: 1