example - java inputstream to byte array
¿Qué hace InputStream.available() en Java? (4)
Considere si escribe software MUY MALO ... y escribe un sistema operativo.
Este sistema operativo toma entrada de teclado entre otras cosas.
Así que le pides a tu sistema operativo que vaya y obtenga alguna entrada de teclado, pero no hay teclas presionadas ni ninguna en el búfer. su sistema operativo completo luego colgará muerto hasta que reciba una entrada de teclado.
Contrastando esto con ''mirar hacia adelante'', pregunta si la KB tiene algún carácter ANTES de realizar la llamada. Obtienes la respuesta NO, entonces tu SO luego va y hace otra cosa.
Ese es el POR QUÉ debe importarle, ahora si luego multiplica eso por cualquier otra tarea potencialmente bloqueadora, puede ver por qué ''mirar hacia adelante'' es crítico.
Porque también se aplica a la SALIDA: una memoria en la interfaz de una unidad de disco también puede inundar los datos en la unidad de disco más rápido de lo que puede procesarlos. Si no sabe que el búfer de la unidad está inundado de datos, la tarea se bloqueará hasta que el búfer pueda aceptar más datos.
Esto también resalta la tontería de ''hay muy pocos usos útiles''.
¿Qué hace InputStream.available()
en Java ? Leí la documentación, pero todavía no puedo hacerlo.
El doc dice:
Devuelve el número de bytes que se pueden leer (o omitir) de esta secuencia de entrada sin que la siguiente persona que llama reciba un método para esta secuencia de entrada. La siguiente persona que llama puede ser el mismo hilo u otro hilo.
El método disponible para la clase InputStream siempre devuelve 0.
¿Qué quieren decir con bloquear ? ¿Significa simplemente una llamada sincronizada?
Y, sobre todo, ¿cuál es el propósito del método available()
?
El bloqueo no se relaciona con los hilos o la sincronización aquí. En su lugar, se relaciona con el bloqueo de IO (consulte this para obtener más información). Si emite una solicitud de lectura y el canal no tiene ninguno disponible, una llamada de bloqueo esperará (o bloqueará) hasta que los datos estén disponibles (o el canal esté cerrado, se genere una excepción, etc.)
Entonces, ¿por qué usar available()
? Así que puedes determinar cuántos bytes leer, o determinar si vas a bloquear.
Tenga en cuenta que Java también tiene capacidades de IO no bloqueantes. Vea here para más detalles
En InputStreams, se dice que las llamadas de read()
son llamadas de método de "bloqueo". Eso significa que si no hay datos disponibles en el momento de la llamada al método, el método esperará a que los datos estén disponibles.
El método available()
le dice cuántos bytes se pueden leer hasta que la llamada a read()
bloquee el flujo de ejecución de su programa. En la mayoría de las secuencias de entrada, todas las llamadas a read()
están bloqueadas, es por eso que disponible devuelve 0 de manera predeterminada.
Sin embargo, en algunos flujos (como BufferedInputStream
, que tienen un búfer interno), algunos bytes se leen y se guardan en la memoria, de modo que puede leerlos sin bloquear el flujo del programa. En este caso, el método available()
le dice cuántos bytes se mantienen en el búfer.
Uno de los usos posiblemente available()
de available()
es usarlo para elegir una longitud de buffer razonable.
static final int LEN = 4096;
long copy(InputStream in, OutputStream out) throws IOException {
int count = 0L;
int avl = in.available();
if (avl == 0) {
// 0 returned without IOException? possibly mean eof?
return 0L;
}
//byte[] buf = new byte[avl == 0 ? LEN : Math.min(avl, LEN)];
byte[] buf = new byte[Math.min(avl, LEN)];
for (int len; (len = in.read(buf)) != -1; count+= len) {
out.write(buf, 0, len);
}
return count;
}
El documento dice:
Devoluciones: una estimación del número de bytes que pueden leerse (o saltarse) desde este flujo de entrada sin bloquear o
0
cuando llega al final del flujo de entrada .
Y
La implementación de este método por una subclase puede elegir lanzar una
IOException
si esta secuencia de entrada se ha cerrado invocando el métodoclose()
.
ACTUALIZAR
Ya sé que la idea no es recomendable. He conocido ese riesgo incluso antes de que el documento JDK advirtiera. (Una vez traté de asignar un búfer de FileInputStream
available
de pocos GB).
Nunca es correcto usar el valor de retorno de este método para asignar un búfer destinado a contener todos los datos en esta secuencia.
Pero, en la programación, no debe haber código never
o always wrong
. Eso es lo que estoy creyendo.