Frage

Ich mache ein Programm in Java mit Sockets. Ich kann Befehle an den Client und von dem Client an den Server senden. Zum Lesen der Befehle, die ich ein BufferedReader verwenden. So schreiben sie, ein PrintWriter Aber jetzt will ich eine Datei übertragen durch , dass Buchse (nicht einfach eine zweite Verbindung erstellen) .
Zuerst habe ich an den Outputstream schreiben, wie viele Bytes die Datei enthält. Zum Beispiel 40000 Bytes. Also schreibe ich die Nummer 40000 durch den Sockel, aber die andere Seite der Verbindung liest 78.

So dachte ich: Das BufferedReader liest mehr als nur die Zeile (durch readLine() Aufruf) und auf diese Art und Weise habe ich einige Bytes aus den Datei-Daten verloren gehen. Weil sie in den Puffer aus dem BufferedReader sind.
So ist die Zahl 78 ist ein Byte der Datei I übertragen werden soll.

Ist auf diese Weise Recht zu denken, oder nicht. Wenn ja, wie dieses Problem sovle.
Ich hoffe, ich habe gut erklärt.


Hier ist mein Code, aber meine Muttersprache ist Niederländisch. So einiger Variablenname kann merkwürdig klingen.

public void flushStreamToStream(InputStream is, OutputStream os, boolean closeIn, boolean closeOut) throws IOException {
    byte[] buffer = new byte[BUFFERSIZE];
    int bytesRead;
    if ((!closeOut) && closeIn) { // To Socket from File
        action = "Upload";
        os.write(is.available()); // Here I write 400000
        max = is.available();
        System.out.println("Bytes to send: " + max);
        while ((bytesRead = is.read(buffer)) != -1) {
            startTiming(); // Two lines to compute the speed
            os.write(buffer, 0, bytesRead);
            stopTiming(); // Speed compution
            process += bytesRead;
        }
        os.flush();
        is.close();
        return;
    }
    if ((!closeIn) && closeOut) { // To File from Socket
        action = "Download";
        int bytesToRead = -1;
        bytesToRead = is.read(); // Here he reads 78.
        System.out.println("Bytes to read: " + bytesToRead);
        max = bytesToRead;
        int nextBufferSize;
        while ((nextBufferSize = Math.min(BUFFERSIZE, bytesToRead)) > 0) {
            startTiming();
            bytesRead = is.read(buffer, 0, nextBufferSize);
            bytesToRead -= bytesRead;
            process += nextBufferSize;
            os.write(buffer, 0, bytesRead);
            stopTiming();
        }
        os.flush();
        os.close();
        return;
    }
    throw new IllegalArgumentException("The only two boolean combinations are: closeOut == false && closeIn == true AND closeOut == true && closeIn == false");
}

Hier ist die Lösung:
Dank James Vorschlag
Ich denke laginimaineb anwser war ein Stück der Lösung.

Lesen Sie die Befehle aus.

DataInputStream in = new DataInputStream(is); // Originally a BufferedReader
// Read the request line
String str;
while ((str = in.readLine()) != null) {
    if (str.trim().equals("")) {
       continue;
    }
    handleSocketInput(str);
}

Nun ist die flushStreamToStream:

public void flushStreamToStream(InputStream is, OutputStream os, boolean closeIn, boolean closeOut) throws IOException {
    byte[] buffer = new byte[BUFFERSIZE];
    int bytesRead;
    if ((!closeOut) && closeIn) { // To Socket from File
        action = "Upload";
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeInt(is.available());

        max = is.available();
        System.out.println("Bytes to send: " + max);
        while ((bytesRead = is.read(buffer)) != -1) {
            startTiming();
            dos.write(buffer, 0, bytesRead);
            stopTiming();
            process += bytesRead;
        }
        os.flush();
        is.close();
        return;
    }
    if ((!closeIn) && closeOut) { // To File from Socket
        action = "Download";
        DataInputStream dis = new DataInputStream(is);
        int bytesToRead = dis.readInt();
        System.out.println("Bytes to read: " + bytesToRead);
        max = bytesToRead;
        int nextBufferSize;
        while ((nextBufferSize = Math.min(BUFFERSIZE, bytesToRead)) > 0) {
            startTiming();
            bytesRead = is.read(buffer, 0, nextBufferSize);
            bytesToRead -= bytesRead;
            process += nextBufferSize;
            os.write(buffer, 0, bytesRead);
            stopTiming();
        }
        os.flush();
        os.close();
        return;
    }
    throw new IllegalArgumentException("The only two boolean combinations are: closeOut == false && closeIn == true AND closeOut == true && closeIn == false");
}

Martijn.

War es hilfreich?

Lösung

Datainputstream ist höchstwahrscheinlich, was Sie verwenden möchten. Auch nicht den zur Verfügung () -Methode verwenden, wie es in der Regel nutzlos ist.

Andere Tipps

Ich bin mir nicht sicher, ob ich Ihre Erklärung befolgt haben.

Allerdings ja - Sie haben keine wirkliche Kontrolle darüber, wie viel ein BufferedReader tatsächlich gelesen wird. Der Punkt, der einem solchen Leser ist, dass es optimistischer Chunks des zugrunde liegenden Ressource liest nach Bedarf seinen Puffer aufzufüllen. Also, wenn Sie erste Anruf readLine, wird er sehen, dass seine internen Puffer nicht genug hat youthe Anforderung zu bedienen, und gehen und lesen aber viele Bytes es fühlt sich an wie in seinen Puffer aus der zugrunde liegenden Quelle , die viel im allgemeinen mehr als Sie für nur dann gefragt. Sobald der Puffer ist aufgefüllt wurde, gibt sie Ihre Linie aus dem gepufferten Inhalt.

So, wenn Sie einen Eingangsstrom in einem BufferedReader wickeln, sollten Sie sicher sein, nur, dass Strom durch die gleichen gepufferten Leser zu lesen. Wenn Sie nicht tun, werden Sie den Verlust von Daten am Ende (wie einige Bytes verbraucht wurden, werden und sitzen nun in der BufferedReader Cache warten bedient zu werden).

A BufferedReader geht davon aus, dass es das einzige von der darunter liegenden Eingangsstroms liest.

Sein Zweck ist es, die Anzahl der liest aus dem zugrunde liegenden Stream zu minimieren (die teuer sind, da sie ziemlich tief delegieren können). Zu diesem Zweck hält es einen Puffer, die es durch das Lese so viele Bytes wie möglich in es in einem Aufruf an den zugrunde liegenden Stream füllt.

Also ja, Ihre Diagnose korrekt.

Nur ein wilder Stich hier - 40000 ist 1001110001000000 in binär. Nun werden die ersten sieben Bits sind hier 1001110 welche 78. Bedeutung, sind Sie 2 Bytes Informationen zu schreiben, aber das Lesen sieben Bits.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top