Junto al artículo anterior, continuaremos aprendiendo operaciones de transmisión de bytes en Java.
Decorator Buffed Stream Bufferedinput/outputStream
La transmisión del decorador es en realidad una transmisión de archivo IO basada en un patrón de diseño "Modo decorador", y nuestra transmisión de búfer es solo una de ellas. Echemos un vistazo.
Antes de esto, utilizamos File Read and Write Streams FileInputStream y FileOutputStream Leer y escribir desde el byte o byte de disco, que requiere mucho tiempo.
Nuestra flujo de búfer puede leer precediendo el número de bytes de una capacidad especificada del disco a la vez en la memoria, y las operaciones de lectura posteriores se leerán directamente de la memoria para mejorar la eficiencia. Echemos un vistazo a la implementación específica de las transmisiones amortiguadas:
Tomemos BufferedInputStream como ejemplo primero, mencionemos brevemente sus propiedades centrales:
BUF es una matriz de bytes utilizada para las lecturas de almacenamiento en búfer. Su valor se llenará continuamente a medida que se lee la transmisión, y las operaciones de lectura posteriores pueden basarse directamente en esta matriz buffered.
Default_buffer_size Especifica el tamaño del búfer predeterminado, es decir, la longitud de la matriz de BUF. Max_buffer_size Especifica el límite superior del búfer.
El recuento apunta al último índice de bytes válido en la matriz amortiguada. POS apunta a la siguiente posición del índice de bytes que se lee.
Markpos y Marklimit se utilizan para repetir las operaciones de lectura.
A continuación, echemos un vistazo a varios constructores de ejemplo de BufferedInputStream:
public bufferedInputStream (inputStream in) {this (in, default_buffer_size);} public BufferedInputStream (inputStream in, int size) {super (in); if (size <= 0) {lanzar nueva ilegalArgumentException ("tamaño de amortiguación <= 0"); } buf = new Byte [size];}En general, el primero solo necesita pasar en una instancia de InputStream que esté "decorada" y use un búfer de tamaño predeterminado. Este último puede indicar explícitamente el tamaño del búfer.
Además, Super (IN) guarda esta instancia de InputStream en el campo Atributo de Atributo de la clase principal FilterInputStream, y todas las operaciones reales de lectura de disco son emitidas por esta instancia de InputStream.
Echemos un vistazo a las operaciones de lectura más importantes y cómo se llena el búfer.
public sincronizado int read () lanza ioexception {if (pos> = count) {relleno (); if (pos> = count) return -1; } return getBufififopen () [pos ++] & 0xff;}Creo que todos ya están familiarizados con este método. Lee el siguiente byte de la transmisión y lo devuelve, pero la implementación en detalles sigue siendo ligeramente diferente.
El recuento de puntos a la siguiente posición del índice de bytes válido en la matriz amortiguada, y POS apunta a la siguiente posición del índice de bytes que se lee. En teoría, POS no puede ser mayor que el recuento, a lo sumo igual a.
Si POS es igual al recuento, significa que se han leído todos los bytes válidos en la matriz de búfer. En este momento, los datos "inútiles" en el búfer deben descartarse y se vuelve a cargar un lote de nuevos datos del disco para llenar el búfer.
De hecho, el método de relleno es lo que hace. Tiene mucho código, así que no te llevaré a analizarlo. Si comprende su función, probablemente sea fácil analizar su implementación.
Si POS todavía es igual al recuento después de que se llama el método de relleno, significa que la instancia de InputStream no ha leído ningún dato de la transmisión, es decir, no hay datos en la secuencia del archivo para leer. Para esto, vea la línea 246 del método de relleno.
En general, si el búfer se llena con éxito, nuestro método de lectura tomará un byte directamente del búfer y lo devolverá a la persona que llama.
Public sincronizado int (byte b [], int off, int len) {// .....}Este método también es un "conocido", ya no tiene ninguna explicación innecesaria, la implementación es similar.
El método de omisión se utiliza para omitir el número de bytes de una longitud especificada para la lectura continua de la transmisión del archivo:
Public Sincronized Long Skip (Long N) {// ......}Una cosa a tener en cuenta es que el método de omisión intenta omitir n bytes, pero no se garantiza que saltará n bytes. El método devuelve el número real de bytes omitidos. Si el número restante de bytes disponibles en la matriz amortiguada es inferior a n, el número real de bytes que se puede omitir en la matriz buffada eventualmente se omitirá.
Finalmente, hablemos de este método cercano:
public void Close () lanza ioexception {byte [] buffer; while ((buffer = buf)! = null) {if (bufupdater.compareandset (this, buffer, null)) {inputStream input = in; in = nulo; if (input! = null) input.close (); devolver; } // el otro reintento en caso de que un nuevo BUF estuviera cubierto en relleno ()}}El método cerrado vaciará la transmisión "decorada" y llamará a su método cercano para liberar recursos relevantes, lo que eventualmente borrará el espacio de memoria ocupado por la matriz de búfer.
BufferedInputStream proporciona capacidades de almacenamiento en búfer, mientras que BufferedOutputStream proporciona capacidades de búfer de escritura, es decir, las operaciones de escritura de memoria no se actualizarán al disco de inmediato, y se guardará temporalmente en el búfer, y se escribirán juntos cuando el búfer esté lleno.
byte buf [] protegido; Conteo de int protegido;
BUF representa el búfer interno, y el recuento representa la capacidad de datos real en el búfer, es decir, el número de bytes efectivos en BUF, en lugar de la longitud de la matriz BUF.
public bufferedOutputStream (outputStream out) {this (out, 8192);} public bufferedOutputStream (outputStream out, int size) {super (out); if (size <= 0) {lanzar nueva ilegalArgumentException ("tamaño de amortiguación <= 0"); } buf = new Byte [size];}Con la misma idea de implementación, es necesario proporcionar una instancia de flujo de salida de salida de salida, y el tamaño del búfer también se puede especificar opcionalmente.
Public sincronizado void write (int b) lanza ioexception {if (count> = buf.length) {flushbuffer (); } buf [count ++] = (byte) b;}El método de escritura primero verificará si el búfer aún puede acomodar esta operación de escritura. Si no se puede iniciar una operación de escritura de disco, todos los datos del búfer se escribirán en el archivo de disco, de lo contrario, el búfer se escribirá primero en el búfer.
Por supuesto, BufferedOutputStream también proporciona un método de descarga para proporcionar una interfaz al exterior, es decir, no tiene que esperar hasta que el búfer esté lleno antes de escribir datos en el disco. También puede llamar explícitamente a este método para borrar el búfer y actualizar los archivos de disco.
public sincronized void flush () lanza ioexception {flushbuffer (); out.flush ();}Con respecto a las transmisiones amortiguadas, el contenido central se introduce como se indicó anteriormente. Esta es una corriente que puede mejorar significativamente la eficiencia. A través de él, se puede reducir el número de accesos de disco y se puede mejorar la eficiencia de ejecución del programa.
No discutiremos la transmisión de serialización de objetos ObjectInput/OutputStream y el Decorator Stream DataAnput/OutputStream en función de los tipos básicos. Cuando aprendamos serialización, discutiremos estas dos transmisiones de bytes nuevamente.
Todos los códigos, imágenes y archivos en el artículo se almacenan en la nube en mi github:
(https://github.com/singleyam/overview_java)
También puede elegir descargar localmente.
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.