12.4 Uso de flujos de procesamiento

Primero, el uso de flujos de procesamiento

La siguiente figura muestra la función de procesamiento de flujos: puede ocultar las diferencias de los flujos de nodos en el dispositivo subyacente y proporcionar métodos de entrada / salida más convenientes para permitir a los programadores relacionar las operaciones de los flujos avanzados.

1.1, los puntos de atención para procesar flujos

1. Use la secuencia de procesamiento para ajustar la secuencia del nodo. El programa utiliza la secuencia de procesamiento para realizar funciones de entrada / salida, permitiendo que la secuencia del nodo interactúe con los dispositivos y archivos de E / S subyacentes.
2. De hecho, tenemos que identificar que el flujo de procesamiento es muy simple, siempre que el parámetro del constructor de flujo no sea un nodo físico, sino un flujo ya existente, entonces este flujo debe ser un flujo de procesamiento, y todos los flujos de nodo son directamente físicos Nodo IO como parámetro constructor.
3. Es muy simple para el programa usar la secuencia de procesamiento. Por lo general, solo necesita pasar una secuencia de nodo como parámetro del constructor al crear la secuencia de procesamiento. La secuencia de procesamiento creada es la secuencia de procesamiento que envuelve la secuencia de nodo.

1.2 Ventajas de procesar flujos

1. Para los desarrolladores, es más fácil usar el flujo de procesamiento para las operaciones de entrada / salida
2. La eficiencia de ejecución del uso del flujo de procesamiento es mayor.
El siguiente programa usa el flujo de procesamiento pritStream para envolver el OutputStream. El flujo de procesamiento después de usar el flujo de procesamiento será más de salida. Conveniente

package section4;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
public class PrintStreamTest
{
    public static void main(String[] args)
    {
        try(
                var pos=new FileOutputStream("src\\section4\\test.txt");
                var ps=new PrintStream(pos))
        {
            //使用PrintStream执行输出
            ps.println("普通字符串");
            //直接使用PrintStream输出对象
            ps.println(new PrintStreamTest());
        }
        catch (IOException IOe)
        {
            IOe.printStackTrace();
        }
    }
}
test.txt文件的内容:
普通字符串
section4.PrintStreamTest@5f184fc6

El programa anterior primero define un flujo de salida de nodo FileOutputStream, luego el programa usa PrintStream para envolver el flujo de salida del nodo, y finalmente usa PrintStream para generar cadenas, objetos de salida ... PrintStream es muy poderoso, y el System.out utilizado en el anterior El tipo para obtener es PrintStream.
Después de usar el flujo de procesamiento para envolver el nodo inferior, al cerrar los recursos de flujo de entrada / salida, simplemente cierre el flujo de procesamiento superior. Al cerrar el flujo de procesamiento superior, el sistema cerrará automáticamente el nodo envuelto por el flujo de procesamiento

En segundo lugar, el sistema de flujo de entrada / salida

2.1 Clasificación del sistema de entrada / salida

El sistema de flujo de entrada / salida de Java se ha mejorado en casi 40 categorías, y la clasificación por función se basa en ciertas reglas:

Clasificación Flujo de entrada de bytes Flujo de salida de bytes Secuencia de entrada de caracteres Secuencia de salida de caracteres
Clase base abstracta Flujo de entrada Flujo de salida Lector Escritor
Archivo de acceso FileInputStream FileOutputStream FileReader FileWriter
Matriz de acceso ByteArrayInputStream ByteArrayOutputStream CharArrrayReader CharArrayWriter
Tubería de acceso PipedInputStream PipedOutputStream PipedReader PipedWriter
Cadena de acceso StringReader StringWriter
Flujo de memoria intermedia BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
Flujo de conversión ObjectInputStream ObjectOutputStream
Clase base abstracta FilterInputStream FilterOutputStream FilterReader FilterWriter
Imprimir flujo PrintStream PrintWriter
Empuje hacia atrás el flujo de entrada PushbackInputStream PushbackReader
Flujo especial DataInputStream DataOutputStream

El rojo en negrita representa el flujo del nodo, que debe estar asociado con el nodo físico especificado; el azul en negrita representa la clase base abstracta y la instancia no se puede crear directamente.
Lo anterior solo resume las secuencias bajo el paquete java.io en el sistema de entrada / salida, así como algunas secuencias de bytes como AudioInputStream, CipherInputStream, DeflaterInputStream, ZioInpuStream, etc. que tienen acceso a archivos de audio, cifrado / descifrado, compresión / descompresión, etc. Tiene funciones especiales y se encuentra debajo de otros paquetes de JDK.

2.2 archivos de texto y archivos binarios

En términos generales, el flujo de bytes es más poderoso que el flujo de caracteres, porque todos los datos en la computadora son binarios, y el flujo de bytes puede manejar todos los archivos binarios, pero el problema es que si usa el flujo de bytes para procesar archivos de texto, Necesita convertir estos caracteres en bytes, lo que aumenta la complejidad de la programación. Por lo tanto, generalmente hay una regla: si el contenido de entrada / salida es contenido de texto, debe considerar el uso de secuencias de caracteres; si el contenido de entrada / salida es contenido binario, debe considerar el uso de secuencias de bytes.
Todos los archivos de contenido de caracteres que se pueden abrir con el Bloc de notas y ver en él se denominan archivos de texto; de lo contrario, se denominan archivos binarios.
Pero, en esencia, todo el texto en la computadora es un archivo binario, y el archivo de texto es solo un caso especial del archivo binario. Cuando el archivo binario puede interpretarse correctamente como caracteres, el archivo binario se convierte en un archivo de texto. Y si desea ver el contenido normal del archivo de texto, debe usar el mismo juego de caracteres al abrir el archivo (el chino simplificado en Windows usa el juego de caracteres GBK por defecto, y Linux en Linux usa el juego de caracteres UTF-8 por defecto).

2.3 Stream para acceder a la matriz

La tabla anterior también enumera una secuencia de nodo que usa una matriz como nodo físico, una secuencia de bytes que usa una matriz de bytes como nodo y una secuencia de caracteres que usa una matriz de caracteres como nodo; esta secuencia de nodo que usa una matriz como nodo físico, excepto para crear un nodo El objeto de secuencia debe dividirse en una matriz de bytes o matriz de caracteres, y su uso es completamente similar al de la secuencia de archivos. Similar a esto, la secuencia de caracteres también puede usar una cadena como un nodo físico, que se usa para lograr la función de leer contenido de una cadena o escribir contenido en una cadena (usando StringBuffer como una cadena). El siguiente programa demuestra el uso de cadenas de caracteres como entrada / salida de nodos físicos.

package section4;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

public class StringNodeTest
{
    public static void main(String[] args)
    {
        var src="从明天起,做一个幸福的人\n"
                +"喂马、劈柴,周游世界\n"
                +"从明天起,关心粮食和蔬菜\n"
                +"我有一所房子,面朝大海,春暖花开\n"
                +"从明天起,和每一个亲人通信\n"
                +"告诉他们我的幸福\n";
        var cbuffer=new char[32];
        var hasRead=0;
        try(
                var sr=new StringReader(src))
        {
            //采用循环方式读取的方式读取字符串
            while((hasRead=sr.read(cbuffer))>0)
            {
                System.out.println(new String(cbuffer,0,hasRead));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try(
                //创建StringWriter时,实际上是一个以StringBuffer作为作为输出节点
                //下面指定的20就是StringBuffer的初始长度
                var sw=new StringWriter(20))
        {
            //调用StringWriter方法执行输出
            sw.write("我有一个美丽的新世界,\n");
            sw.write("她在远方等我,\n");
            sw.write("那里有天真的孩子,\n");
            sw.write("还有姑娘的酒窝\n");
            System.out.println("----下面是sw字符串节点里的内容----");
            System.out.println(sw.toString());
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    }
}

El programa anterior es básicamente similar a los programas FileReader y FileWriter utilizados anteriormente, excepto que al crear objetos StringReader y StringWriter, el nodo de cadena se pasa, no el nodo de archivo. Como String es un objeto de cadena inmutable, StringWriter usa StringBuffer como un nodo de salida.

2.4 Flujos para acceder a la tubería

Cuatro flujos para acceder a la tubería: PipedInputStream, PapedOutputStream, PipedReader, PipedWriter, se utilizan para lograr la función de comunicación entre los procesos, flujo de entrada de bytes, flujo de salida de bytes, flujo de entrada de caracteres, flujo de salida de caracteres.

2.5 Flujo de tampón

Las cuatro secuencias de búfer BufferedInputStream, BufferedOutputStream, BufferedReader y BufferedWriter aumentan la función de caché. Agregar la función de caché puede mejorar la eficiencia de entrada y salida. Después de agregar la función de caché, debe usar flush () para escribir el contenido del área de caché en el nodo físico real.

2.6 Flujo de objetos

El flujo de objetos se utiliza principalmente para realizar la serialización de objetos.

Tres, flujo de conversión

La secuencia de conversión se utiliza para convertir una secuencia de bytes en una secuencia de caracteres, donde InputStreamReader convierte una secuencia de salida de bytes en una secuencia de salida de caracteres; OutputStreamWriter convierte una salida de bytes en una secuencia de salida de caracteres.
Porque aunque el flujo de bytes se usa más ampliamente que el flujo de caracteres, el flujo de caracteres es más conveniente de operar que el flujo de bytes. Si ya hay un flujo que es un flujo de caracteres, es decir, un flujo conveniente, no hay necesidad de convertirlo en un flujo de bytes . Por el contrario, hay una secuencia de bytes, pero se puede determinar que el contenido de la secuencia de bytes es todo texto, por lo que es más conveniente convertirla en una secuencia de caracteres, por lo que solo la secuencia de bytes se convierte en la secuencia de caracteres, y ninguna secuencia de caracteres se convierte en la secuencia de bytes.
Lo siguiente usa la entrada del teclado como un ejemplo para introducir el uso de la secuencia de conversión. Java usa System.in como entrada estándar, es decir, entrada de teclado, pero esta secuencia de entrada estándar es una instancia de InputStream, que no es conveniente de usar, y la entrada de contenido del teclado es todo contenido de texto, por lo que puede usar InputStreamReader para cambiarlo a una secuencia de entrada de caracteres El lector ordinario todavía no es muy conveniente para leer contenido. Puede envolver el lector ordinario en un BufferedReader nuevamente. Puede usar el método ReadeLine () de BufferedReader para leer una línea a la vez. Como se muestra en el siguiente procedimiento:

package section4;
import java.io.*;
public class KeyinTest
{
    public static void main(String[] args)
    {
        try (
                // 将Sytem.in对象转换成Reader对象
                var reader = new InputStreamReader(System.in);
                // 将普通Reader包装成BufferedReader
                var br = new BufferedReader(reader))
        {
            String line = null;
            // 采用循环方式来一行一行的读取
            while ((line = br.readLine()) != null)
            {
                // 如果读取的字符串为"exit",程序退出
                if (line.equals("exit"))
                {
                    System.exit(1);
                }
                // 打印读取的内容
                System.out.println("输入内容为:" + line);
            }
        }
        catch (IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
}

El programa anterior convierte System.in flujo de entrada estándar InputStram byte stream en un flujo de entrada de flujo de caracteres, y luego lo envuelve en un BufferedReader. BufferedReader tiene una función de buffer, que puede leer una línea de texto a la vez, con un salto de línea como una marca, si no hay Cuando se lee una nueva línea, el programa se bloquea hasta que se lee la nueva línea.
Dado que BufferedReader tiene un método readLine (), es fácil leer una línea de contenido, por lo que la secuencia de entrada que lee el contenido de texto a menudo se empaqueta en un BufferedReader, porque es conveniente leer el contenido de texto de la secuencia de entrada.

Cuarto, retroceda el flujo de entrada

En el sistema de flujo de entrada / salida, hay dos flujos especiales que son diferentes, a saber, PushbackInputStream y PushbackReader, que proporcionan los siguientes tres métodos:
(1) vacío no leído (byte [] / char [] buf): uno El contenido de la matriz de bytes / caracteres se devuelve al búfer, lo que permite la lectura repetida del contenido que acaba de leer.
(2) nulo no leído (byte [] / char [] b, int off, int len): empuja el contenido de un conjunto de bytes / caracteres desde off, y la longitud es len bytes / carácter de vuelta al búfer de retroceso Para permitir la lectura repetida del contenido que acaba de leer.
(3) nulo no leído (int b): empuje un byte / carácter nuevamente dentro del búfer de retroceso, permitiendo la lectura repetida del contenido que acaba de leer.
Ambas corrientes de entrada de retroceso tienen un búfer de retroceso. Cuando el programador llama al método no leído () de estas dos corrientes de entrada de retroceso, el sistema empujará el contenido de la matriz especificada nuevamente dentro del área del búfer y empujará Cada vez que se llama al método read () al flujo de entrada, siempre se lee desde el búfer de retroceso, solo después de que el contenido del búfer de retroceso se haya leído completamente, pero la matriz requerida por read () no se haya llenado. Leerá de la secuencia de entrada original. La siguiente figura muestra un diagrama esquemático de este procesamiento de flujo de entrada de retroceso:


Al crear un PushbackInputStream y PushbackReader, debe especificar el tamaño del búfer pushback. La longitud predeterminada del búfer pushback es 1. Si el contenido del búfer pushback en el programa excede el tamaño del búfer pushback, se activará el búfer Pushback. IOException de desbordamiento.
El siguiente programa intenta encontrar la cadena "nuevo PushbackReader" en el programa. Cuando se encuentra la cadena, el programa simplemente imprime el contenido antes de la cadena de destino.

package section4;

import java.io.FileReader;
import java.io.IOException;
import java.io.PushbackReader;

public class PushbackTest
{
    public static void main(String[] args)
    {
        try(
                //创建一个PushbackReader对象,指定推回缓冲区的长度为64
                var pr = new PushbackReader(new FileReader("src\\section4\\PushbackTest.java"),64)
                )
        {
            var buf=new char[32];
            //用于保存上次读取到的字符串
            var lastContent="";
            var hasRead=0;
            while((hasRead=pr.read(buf))>0)
            {
                //将读取到的内容转换为字符串
                var content=new String(buf,0,hasRead);
                var tagetIndex=0;
                //将上次读取到的字符串发和本次读取到的字符串相连
                //查看是否包含目标字符串,如果包含目标字符串
                if((tagetIndex=(lastContent+content).indexOf("new PushbackReader"))>0)
                {
                    //将本次内容和上次内容一起推回缓冲区
                    pr.unread((lastContent+content).toCharArray());
                    //重新定义一个长度为targetIndex的cahr数组
                    if((tagetIndex>32))
                    {
                        buf=new char[tagetIndex];
                    }
                    //再次读取指定长度的内容(就是目标字符串之前的内容)
                    pr.read(buf,0,tagetIndex);
                    //打印读取内容
                    System.out.print(new String(buf,0,tagetIndex));
                    System.exit(0);
                }
                else
                {
                    //打印上次读取内容
                    System.out.print(lastContent);
                    //将本次内容设为上次读取到的内容
                    lastContent=content;
                }
            }
        }
        catch (IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
}

Supongo que te gusta

Origin www.cnblogs.com/weststar/p/12743626.html
Recomendado
Clasificación