not ejemplo java inputstream apache-commons outputstream java-11

not - optional java ejemplo



¿Cuál es el caso de uso de la API de Stream null(entrada/salida) en Java? (3)

A veces desea tener un parámetro del tipo InputStream, pero también poder elegir no alimentar su código con ningún dato. Es probable que en las pruebas sea más fácil burlarse de él, pero en producción puede optar por enlazar una entrada nula en lugar de dispersar su código con s y flags.

comparar:

class ComposableReprinter { void reprint(InputStream is) throws IOException { System.out.println(is.read()); } void bla() { reprint(InputStream.nullInputStream()); } }

con este:

class ControllableReprinter { void reprint(InputStream is, boolean for_real) throws IOException { if (for_real) { System.out.println(is.read()); } } void bla() { reprint(new BufferedInputStream(), false); } }

o esto:

class NullableReprinter { void reprint(InputStream is) throws IOException { if (is != null) { System.out.println(is.read()); } } void bla() { reprint(null); } }

Tiene más sentido con la salida IMHO. La entrada es probablemente más para la consistencia.

Este enfoque se llama Objeto nulo : https://en.wikipedia.org/wiki/Null_object_pattern

Con Java 11, podría inicializar un InputStream como:

InputStream inputStream = InputStream.nullInputStream();

Pero no puedo entender un caso de uso potencial de InputStream.nullInputStream o una API similar para OutputStream es decir, OutputStream.nullOutputStream .

Desde la API Javadocs, pude averiguar que

Devuelve un nuevo InputStream que no lee bytes . La secuencia devuelta está inicialmente abierta. La secuencia se cierra llamando al método close ().

Las llamadas subsiguientes a close() no tienen efecto. Mientras el flujo está abierto, los métodos available() , read() , read(byte[]) , ... skip(long) , y transferTo() comportan como si se hubiera alcanzado el final del flujo.

Revisé más detalladamente las notas de la versión que establecen:

Existen varias ocasiones en las que me gustaría usar métodos que requieran como parámetro un OutputStream / Writer de destino para enviar la salida, pero me gustaría ejecutar esos métodos de forma silenciosa para sus otros efectos.

Esto corresponde a la capacidad en Unix para redirigir la salida del comando a / dev / null, o en DOS para agregar la salida del comando a NUL.

Sin embargo, no entiendo cuáles son esos métodos en la declaración como se indica como ... ejecute esos métodos en silencio para sus otros efectos . (culpe a mi falta de práctica con las API)

¿Puede alguien ayudarme a entender cuál es la utilidad de tener tal flujo de entrada o salida con la ayuda de un ejemplo si es posible?

Edición : una de las implementaciones similares que pude encontrar en la navegación adicional es NullInputStream apache-commons, lo que justifica mucho mejor el caso de uso de pruebas.


Creo que nullOutputStream es muy fácil y claro: solo para descartar la salida (similar a > /dev/null ) y / o para realizar pruebas (no es necesario inventar una OutputStream ).

Un ejemplo (obviamente básico):

OutputStream out = ... // an easy way to either print it to System.out or just discard all prints, setting it basically to the nullOutputStream out.println("yeah... or not"); exporter.exportTo(out); // discard or real export?

Con respecto a nullInputStream , es probablemente más para probar (no me gustan los simulacros) y las API que requieren un flujo de entrada o (esto ahora es más probable) entregar un flujo de entrada que no contiene ningún dato, o no puede entregarlo y donde está null No es una opción viable:

importer.importDocument("name", /* input stream... */); InputStream inputStream = content.getInputStream(); // better having no data to read, then getting a null

Cuando prueba ese importador, puede usar un nullInputStream allí, de nuevo en lugar de inventar su propio InputStream o en lugar de usar un simulacro. Otros casos de uso aquí más bien parecen una solución o mal uso de la API ;-)

Respecto al retorno de un InputStream : eso tiene sentido. Si no tiene ningún dato, es posible que desee devolver nullInputStream lugar de null para que las personas que llaman no tengan que lidiar con null y puedan leer como lo harían si hubiera datos.

Finalmente, estos son solo métodos de conveniencia para hacer que nuestras vidas sean más fáciles sin agregar otra dependencia ;-) y, como ya han dicho otros (comentarios / respuestas), es básicamente una implementación del patrón de objeto nulo .

El uso de null*Stream también podría tener la ventaja de que las pruebas se ejecutan más rápido ... si transmite datos reales (por supuesto ... dependiendo del tamaño, etc.) puede ralentizar sus pruebas innecesariamente y todos queremos que las pruebas completar rápido, ¿verdad? (Algunos se pondrán en ridículo aquí ... bueno ...)


Lo veo como una alternativa más segura (1) y más expresiva (2) a la inicialización de una variable de flujo con null .

  1. No te preocupes por las NPEs.
  2. [Output|Input]Stream es una abstracción. Para devolver un flujo nulo / vacío / simulado, tuvo que desviarse del concepto central hacia una implementación específica.