Estoy haciendo una aplicación cliente-servidor donde el cliente pide un fichero y el servidor lo envía, pero esos ficheros pueden llegar a pesar 1 o 2 GB.
El caso es que he probado con un fichero de menos de 600MB y cuando el cliente ya ha recibido 61MB el servidor da una excepción de OutOfMemoryError.
A ver si me podéis echar una mano, dejo parte del código con el que estoy probando:
Cliente:
Código:
Servidor:public void pedir(String fichero) { try { // Crea la petición y la envía MensajeDameFichero mensaje = new MensajeDameFichero(); mensaje.nombreFichero = fichero; out.writeObject(mensaje); /* Crea un stream de fichero donde almacenará los bytes que va recibiendo y consituirán el fichero recibido */ ficheroRecibido = new FileOutputStream("a/"+mensaje.nombreFichero + EXTENSION); // Comienza a leer los bytes recibidos ObjectInputStream in = new ObjectInputStream(cliente.getInputStream()); MensajeTomaFichero mensajeRecibido; Object mensajeAux; do { mensajeAux = in.readObject(); if (mensajeAux instanceof MensajeTomaFichero) { mensajeRecibido = (MensajeTomaFichero) mensajeAux; ficheroRecibido.write(mensajeRecibido.contenidoFichero, 0, mensajeRecibido.bytesValidos); } else { JOptionPane.showMessageDialog(null, "Error: Mensaje inesperado.", "Error", JOptionPane.ERROR_MESSAGE); break; } } while (!mensajeRecibido.ultimoMensaje); in.close(); close();
Código:
public void enviar(String fichero, ObjectOutputStream out) { try { boolean enviadoUltimo = false; // abre el fichero a enviar y configura las opciones de envío FileInputStream ficheroEnviar = new FileInputStream(fichero); MensajeTomaFichero mensaje = new MensajeTomaFichero(); mensaje.nombreFichero = fichero; // empieza a leer y enviar el fichero System.out.println("Enviando "+fichero); int leidos = ficheroEnviar.read(mensaje.contenidoFichero); while (leidos > -1) { mensaje.bytesValidos = leidos; if (leidos < MensajeTomaFichero.LONGITUD_MAXIMA) { mensaje.ultimoMensaje = true; enviadoUltimo = true; } else { mensaje.ultimoMensaje = false; } out.writeObject(mensaje); if (mensaje.ultimoMensaje) break; // Nuevo mensaje mensaje = new MensajeTomaFichero(); mensaje.nombreFichero = fichero; leidos = ficheroEnviar.read(mensaje.contenidoFichero); } // si ha quedado el último paquete colgando --> lo envias if (!enviadoUltimo) { mensaje.ultimoMensaje = true; mensaje.bytesValidos = 0; out.writeObject(mensaje); } out.close(); System.out.println("Enviado "+fichero); } catch (FileNotFoundException ex) { System.err.println("El fichero solicitado no existe."); } catch (IOException ex) { System.err.println("Excepción inesperada.\n"+ex); } }
He leído en la API que para ficheros mayores a 64K hay que indicar a ambos sockets (socket y serversocket) un tamaño mayor con setReceiveBufferSize(<tamaño>) para que cree los buffers del tamaño adecuado, pero aun indicándole un tamaño de 700MB (mi fichero es de menos de 600MB) sigue saltando la misma excepción.
Muchas gracias por adelantado.