Este artículo analiza la diferencia entre transmisiones de caracteres y transmisiones de bytes en Java para su referencia. El contenido específico es el siguiente
1. ¿Qué es el flujo?
La transmisión en Java es una abstracción de secuencias de bytes. Podemos imaginar que hay una tubería de agua, pero ahora ya no es agua que fluye en la tubería de agua, sino una secuencia de bytes. Al igual que los flujos de agua, las corrientes en Java también tienen una "dirección de flujo". Un objeto del que se puede leer una secuencia de bytes se llama flujo de entrada; Un objeto al que se escribe una secuencia de bytes se llama flujo de salida.
2. Byte Stream
La unidad más básica del procesamiento de la corriente de bytes en Java es un solo byte, que generalmente se usa para procesar datos binarios. Las dos clases de transmisión de bytes más básicas en Java son InputStream y OutputStream, que representan el grupo de flujos de bytes de entrada básicos y flujos de bytes de salida, respectivamente. Tanto la clase InputStream como la clase OutputStream son clases abstractas. En uso real, generalmente usamos una serie de subclases de ellas proporcionadas en la biblioteca de clase Java. Tomemos la clase InputStream como ejemplo para introducir la transmisión de bytes en Java.
La clase InputStream define un método básico que lee para leer bytes de una secuencia de bytes. La definición de este método es la siguiente:
public abstract int read () lanza IOException;
Este es un método abstracto, es decir, cualquier clase de flujo de byte de entrada derivada de InputStream necesita implementar este método. La función de este método es leer un byte de la secuencia de bytes y return -1 si alcanza el final, de lo contrario devolver el byte de lectura. Lo que debemos tener en cuenta sobre este método es que seguirá bloqueando y devolviendo un byte de lectura o -1. Además, las transmisiones de bytes no admiten el almacenamiento en caché de forma predeterminada, lo que significa que cada vez que se llama el método de lectura, el sistema operativo solicitará al sistema operativo que lea un byte, que a menudo se acompaña de disco IO, por lo que será relativamente ineficiente. Algunos amigos pueden pensar que el método sobrecargado de lectura en la clase InputStream con matriz de bytes, ya que los parámetros pueden leer múltiples bytes a la vez sin el disco frecuente IO. Entonces, ¿es este el caso? Echemos un vistazo al código fuente de este método:
public int read (byte b []) lanza ioexception {return read (b, 0, b.length);}Llama a otra versión del método de sobrecarga de lectura, por lo que continuaremos siguiendo:
public int read (byte b [], int off, int len) lanza ioexception {if (b == null) {throw new nullPointerException (); } else if (OFF <0 || Len <0 || Len> B.Length - Off) {tire nuevo índiceuToUtofBoundseException (); } else if (len == 0) {return 0; } int c = read (); if (c == -1) {return -1; } b [OFF] = (byte) c; int i = 1; intente {for (; i <len; i ++) {c = read (); if (c == -1) {break; } b [OFF + I] = (byte) c; }} catch (ioException ee) {} return i; }En el código anterior, podemos ver que, de hecho, el método Read (byte []) también usa un bucle para llamar al método Read () para leer en una matriz de bytes "al mismo tiempo", por lo que esencialmente este método no usa un búfer de memoria. Para usar búferes de memoria para mejorar la eficiencia de lectura, debemos usar BufferedInputStream.
3. Transmisión de personajes
La unidad más básica de procesamiento de la corriente de caracteres en Java es el símbolo Unicode (2 bytes de tamaño), que generalmente se usa para procesar datos de texto. El llamado símbolo de Unicode es una unidad de código Unicode con un rango de 0x0000 ~ 0xffff. Cada número en el rango anterior corresponde a un carácter. El tipo de cadena en Java codifica caracteres en las reglas de Unicode de forma predeterminada y luego los almacena en la memoria. Sin embargo, a diferencia del almacenado en la memoria, los datos almacenados en el disco generalmente tienen varios métodos de codificación. Utilizando diferentes métodos de codificación, los mismos caracteres tendrán diferentes representaciones binarias. En realidad, las transmisiones de personajes funcionan así:
FLUJO DE CARÁCTER DE CARÁCTER: Convierta la secuencia de caracteres (en realidad una secuencia de símbolos Unicode) en la secuencia de bytes bajo el método de codificación especificado, y luego escríbala en el archivo;
FRESCURA DE CARÁCTER DE ENTRADA: decodifique la secuencia de bytes que se lee en la secuencia de caracteres correspondiente (en realidad la secuencia de símbolos Unicode) en el método de codificación especificado para que pueda almacenarse en la memoria.
Utilizamos una demostración para profundizar nuestra comprensión de este proceso. El código de muestra es el siguiente:
import java.io.filewriter; import java.io.ioException; public class FileWriterDemo {public static void main (string [] args) {FileWriter filewriter = null; Pruebe {try {filewriter = new FileWriter ("Demo.txt"); FileWriter.Write ("demo"); } Finalmente {FileWriter.Close (); }} catch (ioException e) {E.PrintStackTrace (); }}}En el código anterior, usamos FileWriter para escribir los cuatro caracteres "demo" en demo.txt. Usamos el editor hexadecimal Winhex para ver el contenido de Demo.txt:
Como se puede ver en la figura anterior, la "demostración" que escribimos está codificada como "64 65 6d 6f", pero no especificamos explícitamente el método de codificación en el código anterior. De hecho, cuando no especificamos, el método de codificación de caracteres predeterminado del sistema operativo se usa para codificar los caracteres que queremos escribir.
Dado que la secuencia de caracteres realmente necesita completar la conversión de la secuencia de símbolos de Unicode al método de codificación correspondiente antes de la salida, usará un búfer de memoria para almacenar la secuencia de bytes convertida y esperar a que la conversión se complete antes de escribir en el archivo de disco juntos.
4. La diferencia entre la corriente de personaje y la corriente de byte
Después de la descripción anterior, podemos saber que las principales diferencias entre las transmisiones de bytes y las transmisiones de caracteres se reflejan en los siguientes aspectos:
La unidad básica de la operación de la corriente de byte es bytes; La unidad básica de la operación de la secuencia de caracteres son los símbolos Unicode.
Por defecto, la secuencia de bytes no usa buffers; La corriente de personajes usa buffers.
Una secuencia de bytes generalmente se usa para procesar datos binarios. De hecho, puede procesar ningún tipo de datos, pero no admite escribir o leer símbolos de Unicode directamente; Una secuencia de caracteres generalmente procesa datos de texto, lo que admite escribir y leer símbolos Unicode.
Lo anterior es parte de mi comprensión de las transmisiones de personajes y las transmisiones de bytes en Java. Si hay descripciones poco claras o inexactas, espero que pueda corregirlas. Gracias.