Estoy creando una aplicación de servidor de archivo para la asignación de la escuela. Lo que tengo actualmente es un simple Client clase que envía una imagen a través de TCP y un Server clase que recibe y los escribe en el archivo.

este es mi código de cliente

import java.io.*;
import java.net.*;

class Client {
    public static void main(String args[]) throws Exception {
        long start = System.currentTimeMillis();
        Socket clientSocket = new Socket("127.0.0.1", 6789);
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

        File file = new File("hot.jpg");
        FileInputStream fin = new FileInputStream(file);
        byte sendData[] = new byte[(int)file.length()];
        fin.read(sendData);

        outToServer.write(sendData, 0, sendData.length);
        clientSocket.close();

        long end = System.currentTimeMillis();
        System.out.println("Took " + (end - start) + "ms");
    }
}

y este es mi código de servidor.

import java.io.*;
import java.net.*;

class Server {
    public static void main(String args[]) throws Exception {
        ServerSocket serverSocket = new ServerSocket(6789);
        Socket connectionSocket = serverSocket.accept();
        DataInputStream dis = new DataInputStream(connectionSocket.getInputStream());

        byte[] receivedData = new byte[61500]; //<- THIS NUMBER

        for(int i = 0; i < receivedData.length; i++)
            receivedData[i] = dis.readByte();

        connectionSocket.close();
        serverSocket.close();

        FileOutputStream fos = new FileOutputStream("received.jpg");
        fos.write(receivedData);
        fos.close();
    }
}

Mi pregunta es cómo obtener el tamaño del archivo que está siendo enviado. Si marca la Server código verás que he codificado el número es decir, 61500_es en el momento. ¿Cómo puedo recuperar este número de forma dinámica?

O, estoy haciendo esto por el camino equivocado? Lo que una solución alternativa sería?

OriginalEl autor David Weng | 2011-05-10

2 Comentarios

  1. 7

    Agregar un «campo de longitud» antes de enviar el archivo. (Tenga en cuenta que, desde que se lee el archivo a la memoria el tamaño máximo de un archivo puede ser ~2GB.)


    Antes de enviar el archivo, escriba la longitud del archivo:

      outToServer.writeInt(sendData.length);

    Y cuando reciben leer la longitud de la primera, y el uso como un longitud:

      int dataLength = dis.readInt()
      byte[] receivedData = new byte[dataLength];

    Una mejor manera sería no para leer el archivo en la memoria de la primera, pero a la transferencia directamente desde el FileInputStream – entonces, usted puede transferir archivos más grandes!

    Gracias tio, hizo el trabajo.
    No veo donde puedo leer el archivo en la memoria antes de enviarlo? Dónde está y cómo puedo evitarlo?
    Weng: En el punto donde el uso de ‘<- ESTE NÚMERO de » eres asignar suficiente memoria para el archivo entero. Rara vez se necesita para hacerlo, y no escala a, incluso moderadamente archivos de gran tamaño.

    OriginalEl autor dacwe

  2. 2

    Si conoces la longitud, el uso de readFully() es mucho más eficiente que la lectura de un byte a la vez.

    En este caso, usted no necesita saber la longitud, se puede escribir el bucle para leer/escribir los datos tanto como usted consigue.

    InputStream is = connectionSocket.getInputStream();
    
    byte[] bytes = new byte[8192];
    int len;
    while((len = is.read(bytes)) > 0)
        fos.write(bytes, 0, len);

    Puede evitar leer el archivo de la memoria por la copia de los datos a medida que lee.

    FileInputStream fis = new FileInputStream(filename);
    OutputStream os = socket.getOutputStream();
    
    byte[] bytes = new byte[8192];
    int len;
    while((len = fis.read(bytes)) > 0)
        os.write(bytes, 0, len);

    Puede utilizar Apache IOUtils.copia() para realizar la copia de una corriente a otra, si lo desea.

    Este enfoque tiene la ventaja de que el archivo puede ser de cualquier tamaño (más de 2 GB). El uso de una matriz está limitado a 2 GB (y utiliza más memoria)

    el segundo ejemplo de código no tiene mucho sentido
    es básicamente un código de copia del primer ejemplo. Lo que no tiene sentido?

    OriginalEl autor Peter Lawrey

Dejar respuesta

Please enter your comment!
Please enter your name here