Pregunta

Estoy haciendo un programa en Java con sockets. Puedo enviar comandos al cliente y desde el cliente al servidor. Para leer los comandos que utilizo un BufferedReader. Para escribir ellos, un PrintWriter Pero ahora quiero transferir un archivo a través de que Toma de (No basta con crear una segunda conexión) .
Primero escribo a la forma en OutputStream la cantidad de bytes que contiene el archivo. Por ejemplo 40000 bytes. Así que escribir el número 40000 través de la toma, pero el otro lado de la conexión lee 78.

Así que estaba pensando: La BufferedReader lee más que la línea (llamando readLine()) y en esa manera de que pierda algunos bytes desde el archivo-datos. Porque están en la memoria intermedia de la BufferedReader.
Por lo que el número 78 es un byte del archivo que desea transmitir.

¿Es esta manera de pensar bien, o no. Si es así, cómo sovle este problema.
Espero haber explicado bien.


Aquí está mi código, pero mi idioma por defecto es el holandés. Por lo que algunos nombre-variable puede sonar Stange.

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");
}

Aquí está la solución:
Gracias a James sugerencia
Creo laginimaineb anwser era un pedazo de la solución.

Leer los comandos.

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);
}

Ahora el 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.

¿Fue útil?

Solución

DataInputStream es muy probable que lo que desea utilizar. Además, no utilizar el método disponible () ya que es generalmente inútil.

Otros consejos

No estoy seguro de que he seguido su explicación.

Sin embargo, sí - que no tiene control real sobre la cantidad realmente leerá un BufferedReader. El punto de un lector de este tipo es que con optimismo lee trozos de los recursos que subyacen como sea necesario para reponer su memoria intermedia. Así que la primera vez que readLine llamada, se verá que su buffer interno no tiene suficiente para servir youthe solicitud, y será ir fuera y leer sin embargo muchos bytes que se siente como en su buffer de la fuente subyacente , que generalmente será mucho más de lo que pidió en ese momento. Una vez que la memoria intermedia ha estado poblada, devuelve su línea a partir del contenido tamponada.

Por lo tanto, una vez que se coloca un flujo de entrada en un BufferedReader, usted debe estar seguro de que sólo para leer la corriente a través del mismo lector tamponada. Si no lo hace va a terminar la pérdida de datos (como se habrá consumido algunos bytes y ahora está sentado en la caché del BufferedReader esperando a ser servido).

A BufferedReader asume que es la única lectura del flujo de entrada subyacente.

Su propósito es reducir al mínimo el número de lecturas de la corriente subyacente (que son caros, ya que pueden delegar bastante profundamente). Para ello, se mantiene un buffer, que se llena mediante la lectura de tantos bytes como sea posible en ella en una sola llamada a la corriente subyacente.

Así que sí, su diagnóstico es preciso.

Sólo una puñalada salvaje aquí - 40000 es 1001110001000000 en binario. Ahora, los siete primeros bits son aquí 1.001.110 que es 78. Esto quiere decir que usted está escribiendo 2 bytes de información, pero la lectura de siete bits.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top