¿Cómo se puede forzar una descarga en un objeto OutputStream sin cerrarlo?

Mi pregunta se encuentra en los siguientes supuestos que espero sean verdaderos, porque creo que estos como los leí mientras Googling mis problemas:

  1. El cierre de OutputStream de un socket también cierra el socket
  2. El método flush () de OutputStream no hace nada

Por lo tanto, básicamente, necesito eliminar de todos modos los datos de mi objeto OutputStream para que mi aplicación funcione.

Si está interesado en los detalles, consulte los dos enlaces siguientes:

. Comportamiento extraño: enviar la imagen desde un teléfono Android al servidor Java (funcionando el código)

Este problema se resolvió mediante el cierre de OutputStream. Haciendo que descargó todos los datos al otro extremo del zócalo e hizo funcionar mi aplicación más, pero esta solución pronto dio lugar a problema número 2 – el socket correspondiente también se cierra:

. SocketException – 'Socket está cerrado' incluso cuando isConnected () devuelve true

Puede llamar al método de descarga de OutputStream en lugar de cerrar. Las clases concretas que heredan de OutputStream reemplazarán a flush () para hacer algo distinto de nada (escribir los datos en un archivo o enviarlos a través de la red).

El método flush () de OutputStream no hace nada.

Esto es incorrecto.

Es cierto que la implementación de base de flush() proporcionada por la clase OutputStream no hace nada. Sin embargo, su aplicación llamará a la versión de ese método que se proporciona por la clase de flujo real que está utilizando. Si la clase de flujo no tiene semántica de escritura directa, reemplazará flush() para hacer lo que se requiere.

En resumen, si se necesita una descarga (y se requiere para un flujo de salida de Socket), entonces llamar a flush() hará lo correcto. (Si alguna fuente de Internet le informa de lo contrario, es incorrecto o lo está malinterpretando).


FYI, la razón de que la base OutputStream implementa flush() como un no-op es que:

  • Algunas clases de flujo de salida no necesitan hacer nada cuando se vacían; Por ejemplo, ByteArrayOutputStream , y
  • Para las clases de flujo en las que flush() no es un no op, no hay forma de implementar la operación en el nivel de clase base.

Podrían (en teoría) han diseñado las API de flujo para que OutputStream fuera una clase abstracta (y flush() un método abstracto) o una interfaz. Sin embargo esta API se congeló efectivamente antes de Java 1.0, y en ese momento no había suficiente experiencia con la programación práctica de Java para darse cuenta de que el diseño de la API era subóptima.

El cierre de OutputStream de un socket también cierra el socket

Cierto.

El método flush () de OutputStream no hace nada

Falso. Hay anulaciones. Vea el Javadoc para FilterOutputStream.flush() , BufferedOutputStream.flush() , ObjectOutputStream.flush() , por nombrar algunos.

Así que su problema inicial es inexistente, por lo que no tiene necesidad de la "solución" que causa el problema # 2.

¿Realmente necesitas limpiarla? También tuve un problema, donde el oyente en el servidor c # no podía recibir los datos enviados desde android (traté de obtener los datos de forma sincrónica).

Estaba seguro de que esto es porque en el lado de Android, el siguiente código no funcionó.

 OutputStream str = btSocket.getOutputStream(); str.write(data_byte); // "This implementation does nothing" str.flush(); 

Resultó que si utilizo la recuperación de datos asíncronos en el listener del servidor – obtiene los datos, y no se necesita flush () en el lado del cliente!

Voy a tomar una puñalada en ella. Estaba teniendo el mismo problema. Cerrando el outputtream es la única manera que puedo "limpiar" los datos. Pero ya que todavía necesito el outputstream que no es una opción. Así que primero yo envío la longitud de la matriz del byte, out.writeInt, entonces el arsenal sí mismo. Cuando todos los bytes se han leído, es decir, buffer.length == in.readInt () i break loop

  ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; byte[] fileBytes; int n; int length; try { size = in.readInt(); while((n = in.read(buffer)) != -1) { dataBuffer.write(buffer, 0, n); if(dataBuffer.toByteArray().length == length) { fileBytes = dataBuffer.toByteArray(); break; } } } 

Yo tuve el mismo problema. Añada "\ n" al final de la secuencia. Flush funciona, pero el destinatario no sabe si el mensaje terminó

SÍ en Android flush () no hacer nada (ejemplo basado en api 23)

 public Socket() { this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl(); this.proxy = null; } public class PlainSocketImpl extends SocketImpl { @Override protected synchronized OutputStream getOutputStream() throws IOException { checkNotClosed(); return new PlainSocketOutputStream(this); } } private static class PlainSocketOutputStream extends OutputStream { // doesn't override base class flush(); } 

Para vaciar el flujo de salida sin cerrar el zócalo puede salida de apagado:

 protected void shutdownOutput() throws IOException 

– esto cerrará el descriptor de archivo WRITE.

En lugar de utilizar el flujo de salida, puede escribir directamente en el descriptor de archivo o creando su propia implementación de socket con OutputStream, que reemplazará el método de descarga (por ejemplo, mediante una implementación de socket de Berkeley en c).

  • Recibir mensaje de difusión en Android
  • AsyncSocket en java?
  • cómo leer el flujo de entrada de socket en Android
  • Android java.net.SocketException: socket failed: EACCES (Permiso denegado)
  • Cómo implementar un servidor HTTP en android
  • HttpsURLconnection para publicar y obtener en Android
  • Uso incorrecto de BufferedReader
  • Cliente de Android enviar archivos grandes utilizando Socket, el archivo recibido por el servidor es incompleta
  • Apache HttpClient 4.0 falla en el tiempo de espera para socket en Android
  • Socket no lanza una excepción aunque no puede conectarse
  • ¿Tiene sentido tener más de un socket UDP Datagram en espera? ¿Los paquetes "simultáneos" han sido eliminados o puestos en cola por el núcleo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.