Domanda

Sto facendo un programma in Java con Sockets. Posso inviare comandi al cliente e dal client al server. Per leggere i comandi che uso un BufferedReader. Per scrivere loro, un PrintWriter Ma ora voglio trasferire un file tramite che presa (Non è sufficiente creare un secondo collegamento) .
Prima scrivo al OutputStream come quanti byte il file contiene. Per esempio 40000 byte. Così scrivo il numero di 40000 attraverso la presa, ma l'altro lato della connessione recita 78.

Quindi stavo pensando: Il BufferedReader legge più di una semplice linea di (chiamando readLine()) e così perdo alcuni byte dal file-dati. Perché sono nel buffer dal BufferedReader.
Così il numero 78 è un byte del file che voglio trasmettere.

E 'questo modo di pensare giusto, o no. Se sì, come a sovle questo problema.
Spero di aver spiegato bene.


Ecco il mio codice, ma la mia lingua di default è l'olandese. Così alcuni nome-variabile può suonare 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");
}

Ecco la soluzione:
Grazie a James suggerimento
Credo che laginimaineb anwser era un pezzo della soluzione.

Leggi i comandi.

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

Ora la 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.

È stato utile?

Soluzione

DataInputStream è più probabile che ciò che si desidera utilizzare. Inoltre, non utilizzare il metodo disponibile () come è generalmente inutile.

Altri suggerimenti

Non sono sicuro che ho seguito la tua spiegazione.

Tuttavia, sì - si ha alcun reale controllo su quanto un BufferedReader sarà effettivamente letto. Il punto di tale lettore è che legge ottimisticamente blocchi di risorsa in oggetto come necessario per riempire il buffer. Quindi, quando si prima readLine chiamata, vedrà che il suo buffer interno non ha abbastanza per servire youthe richiesta, e sarà andare fuori e leggere comunque molti byte si sente come nel suo buffer dalla sorgente sottostante , che sarà generalmente molto più di quanto avete chiesto proprio in quel momento. Una volta che il buffer è stato popolato, restituisce la linea dal contenuto tamponata.

In questo modo una volta che si avvolge un flusso di input in un BufferedReader, si dovrebbe essere sicuri di leggere solo quel flusso attraverso lo stesso lettore di buffer. Se non si finirà per perdere i dati (come sarà stata consumata qualche byte e sono ora seduti nella cache del BufferedReader attesa di essere serviti).

Un BufferedReader presuppone che è l'unica lettura dal flusso di input sottostante.

Il suo scopo è quello di ridurre al minimo il numero di letture dal flusso sottostante (che sono costosi, in quanto possono delegare abbastanza profondamente). A tal fine, mantiene un buffer, che riempie leggendo tanti byte possibili in esso in una singola chiamata al flusso sottostante.

Quindi sì, la vostra diagnosi è precisa.

Basta una pugnalata selvaggio qui - 40000 è 1001,110001 mille miliardi in binario. Ora, i primi sette bit qui ci sono 1.001.110, che è 78. Significato, si sta scrivendo 2 byte di informazioni, ma la lettura di sette bit.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top