Question

Je fais un programme en Java avec les sockets. Je peux envoyer des commandes au client et du client vers le serveur. Pour lire les commandes que j'utilise un BufferedReader. Pour les écrire, un PrintWriter Mais maintenant je veux transférer un fichier via socket (pas simplement créer une seconde connexion) .
Tout d'abord je vous écris au outputstream comment nombre d'octets contient le fichier. Par exemple 40000 octets. Alors j'écris le nombre 40000 par la prise, mais l'autre côté de la connexion se lit 78.

Je pensais: Le BufferedReader lit plus que la ligne (en appelant readLine()) et de cette façon, je perds quelques octets à partir du fichier-données. Parce qu'ils sont dans la mémoire tampon de la BufferedReader.
Ainsi, le 78 numéro est un octet du fichier que je veux transmettre.

est cette façon de penser droit, ou non. Si oui, comment sovle ce problème.
J'espère avoir bien expliqué.


Voici mon code, mais ma langue par défaut est le néerlandais. Ainsi, une variable nom peut paraître 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");
}

Voici la solution: Merci à la suggestion James Je pense que laginimaineb anwser était une partie de la solution.

Lire les commandes.

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

Maintenant, le 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.

Était-ce utile?

La solution

DataInputStream est très probablement ce que vous voulez utiliser. En outre, ne pas utiliser la méthode disponible () comme il est généralement inutile.

Autres conseils

Je ne suis pas sûr que je l'ai suivi votre explication.

Cependant, oui - vous avez aucun contrôle réel sur combien un BufferedReader va lire réellement. Le point d'un tel lecteur est qu'il lit des morceaux de la façon optimiste ressource sous-jacente au besoin pour reconstituer son tampon. Donc, lorsque vous readLine d'appel, il verra que sa mémoire tampon interne ne dispose pas de suffisamment pour servir youthe demande, et en aller et lire cependant de nombreux octets, il se sent comme dans son tampon de la source sous-jacente , qui sera généralement beaucoup plus que vous avez demandé ce moment-là. Une fois a été rempli la mémoire tampon, il retourne votre ligne à partir du contenu en mémoire tampon.

Ainsi une fois que vous enveloppez un flux d'entrée dans un BufferedReader, vous devez être sûr de ne lire que ce flux par le même lecteur en mémoire tampon. Si vous ne vous finirez par perdre des données (comme certains octets aura été consommé et sont maintenant assis dans le cache de BufferedReader en attente d'être servi).

A BufferedReader suppose qu'il est le seul à la lecture à partir du flux d'entrée sous-jacente.

Il a pour objectif de réduire le nombre de lectures du flux sous-jacent (qui sont coûteux, car ils peuvent déléguer assez profondément). À cette fin, il garde un tampon, qu'il remplit en lisant autant d'octets que possible dans dans un seul appel au flux sous-jacent.

Alors oui, votre diagnostic est exact.

Juste un coup de poignard sauvage ici - 40000 est 1001110001000000 en binaire. Maintenant, les sept premiers bits ici sont 1.001.110 qui est 78. Cela signifie que vous écrivez 2 octets d'information, mais la lecture de sept bits.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top