1. Descripción general del flujo de E/S
1.IO: entrada (la entrada lee datos)/salida (la salida escribe datos)
2. Stream: es un concepto abstracto y un término general para la transmisión de datos. Es decir, la transmisión de datos entre dispositivos se llama flujo. La esencia del flujo es la transmisión de datos. El flujo IO se utiliza para manejar la transmisión de datos. Problemas entre dispositivos.
3. Aplicaciones comunes: carga, descarga, copia de archivos, etc.
Un archivo generalmente se compone de una serie de bytes o caracteres. La secuencia de bytes que constituye el archivo se denomina secuencia de bytes y la secuencia de caracteres que constituye el archivo se denomina secuencia de caracteres. Java se puede dividir en flujos de entrada y flujos de salida según la dirección del flujo. El flujo de entrada es el proceso de cargar datos de archivos u otros dispositivos de entrada en la memoria; el flujo de salida es todo lo contrario, guardar datos en la memoria en archivos u otros dispositivos de salida. Consulte la figura siguiente para obtener más detalles:
2. Clasificación del flujo IO
2.1 Clasificación según la dirección del flujo de datos:
Flujo de entrada: Leer datos Leer datos del disco duro a la memoria.
Flujo de salida: escribir datos Escriba los datos del programa en el disco duro.
2.2 Según tipo de datos:
Flujo de bytes: flujo de entrada de bytes/flujo de salida de bytes
Flujo de caracteres: flujo de entrada de caracteres/flujo de salida de caracteres
2.3 escenarios de aplicación de flujo IO:
Archivos de texto sin formato, utilice preferentemente secuencias de caracteres
Para archivos binarios como imágenes, vídeos y audios, se prefieren los flujos de bytes.
Si no está seguro del tipo de archivo, utilice primero el flujo de bytes. El flujo de bytes es un flujo universal.
2.4 InputStream (flujo de entrada de bytes), OutputStream (flujo de salida de bytes), Lector (flujo de entrada de caracteres), Writer (flujo de salida de caracteres)
2.4.1 InputStream (flujo de entrada de bytes)
InputStream es un flujo de entrada de bytes. InputStream es una clase abstracta. Todas las clases que heredan InputStream son flujos de entrada de bytes. Puede comprender principalmente las siguientes subclases:
Introducción al método principal:
vacío |
close() |
resumen entero |
read() |
En t |
read(byte[] b) |
En t |
read(byte[] b, int off, int len) |
2.4.2 OutputStream (flujo de salida de bytes)
Introducción al método principal:
vacío |
close() |
vacío |
Flush() |
vacío |
write(byte[] b) |
vacío |
write(byte[] b, int off, int len) |
vacío abstracto |
write(int b) |
2.4.3 Lector (flujo de entrada de caracteres)
Todos los lectores heredados son flujos de entrada de caracteres.
Introducción al método principal:
vacío abstracto |
close() |
En t |
read() |
En t |
read(char[] cbuf) |
resumen entero |
read(char[] cbuf, int off, int len) |
2.4.4 Escritor (flujo de salida de caracteres)
Todos los Writer heredados son flujos de salida de caracteres.
Introducción al método principal:
Escritor |
append(char c) |
vacío abstracto |
close() |
vacío abstracto |
Flush() |
vacío |
write(char[] cbuf) |
vacío abstracto |
write(char[] cbuf, int off, int len) |
vacío |
write(int c) |
vacío |
write(String str) |
vacío |
write(String str, int off, int len) |
3. Flujo de archivos
3.1 FileInputStream ( flujo de entrada de bytes de archivo )
FileInputStream: obtiene bytes de entrada de un archivo en el sistema de archivos;
FileInputStream (nombre de cadena): crea un FileInputStream abriendo una conexión al archivo real, que recibe el nombre del nombre de la ruta en el sistema de archivos;
paso:
1. Cree un objeto de flujo de entrada de bytes
2. Llame al método de lectura de datos del objeto de flujo de entrada de bytes.
3. Liberar recursos
Leer datos del flujo de bytes:
nombre del método |
ilustrar |
int lectura() |
Lea un byte de datos del flujo de entrada. Cuando el valor de retorno es -1, indica que el archivo ha sido leído (se leerán varias llamadas en secuencia) |
En t |
read(byte[] b) |
int |
read(byte[] b, int off, int len) |
InputStream in = new FileInputStream("d:/a.txt");
int c = 0;
while((c = in.read()) != -1){
System.out.println(c);
}
in.close();
上述代码在执行时:如果在执行in.read()
时没有读取到末尾,即文件还有可读取的数据,in.read()
方法会返回下一个可用字节的整数值(0-255之间)。如果已经读取到了文件末尾,in.read()
方法会返回-1。
3.2 FileOutputStream(文件字节输出流)
字节流写入数据常用的三种方式:
方法名称 |
说明 |
void write(int b) |
将指定的字节写入此文件输出流 一次写一个字节数据 |
void write(byte[] b) |
将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据 |
void write(byte[] b, int off, int len) |
将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据 |
void write(byte[] b, int off, int len)
是Java中OutputStream
类的一个方法,用于将指定字节数组中的一部分数据写入输出流。
参数解释:
b
:要写入的字节数组。off
:写入的起始偏移量,即从数组的第off
个位置开始写入数据。len
:要写入的字节数,即写入b
数组中从off
位置开始的连续len
个字节。
如何追加写入数据:
El flujo de bytes escribe datos a través de new FileOutputStream(new File("mayikt.txt"), true); para indicar datos escritos adicionales. Si el segundo parámetro es verdadero, el flujo de bytes se escribe al final del archivo. Este método implementa la escritura de anexos FileOutputStream
estableciendo el segundo parámetro en al construir el objeto.true
InputStream in = new FileInputStream("d:/a.txt");
OutputStream out = new FileOutputStream("d:/aa.txt");
int c = 0;
while((c = in.read()) != -1){
out.write(c);
}
in.close();
out.close();
Lea 1024 bytes a la vez, un kb:
import java.io.*;
public class Demo03 {
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("d:/apache-tomcat-8.5.75.zip");
OutputStream os = new FileOutputStream("d:/tomcat.zip",true);//append:true 追加
byte[] b = new byte[1024];
int len = 0;
while ( (len = is.read(b)) != -1 ){
os.write(b,0,len);
}
//关闭IO流管道 关闭的时候会有刷新作用
is.close();
os.close();
}
}
3.3 FileReader (flujo de entrada de caracteres de archivo)
FileReader lee archivos en unidades de un carácter, es decir, lee dos bytes a la vez, como por ejemplo:
Reader r = new FileReader("E:/a.txt");
int c = 0;
while((c = r.read()) != -1){
char ch = (char)c;
System.out.println(ch);
}
r.close();
3.4 FileWriter (flujo de salida de caracteres de archivo)
Reader r = new FileReader("d:/a.txt");
Writer w = new FileWriter("d:/aaa.txt",true);
int c = 0;
while((c = r.read()) != -1){
char ch = (char)c;
w.write(ch);
}
r.close();
w.close();
4. Flujo de búfer
La forma tradicional de leer o escribir datos byte a byte provocará llamadas frecuentes al kernel del sistema (modo de usuario → cambio de modo kernel), lo cual es muy ineficiente.
Podemos utilizar un flujo de búfer de bytes. El búfer es un concepto de área de memoria, similar a un grupo, que escribe o lee datos de manera "rápida" para reducir la frecuencia de las llamadas al sistema.
El constructor pasa un objeto de flujo de bytes, no una ruta de archivo. El flujo de búfer proporciona un búfer que encapsula datos para lectura y escritura en bloques. La lectura y escritura de datos aún depende del objeto de flujo de bytes.
Nota: El tamaño de búfer predeterminado de la secuencia de bytes almacenados en búfer es 8K, es decir: 8192 bytes.
Los flujos almacenados en búfer existen principalmente para mejorar la eficiencia y reducir la cantidad de lecturas físicas. Los flujos almacenados en búfer incluyen principalmente: BufferedInputStream, BufferedOutputStream, BufferedReader y BufferedWriter. BufferedReader proporciona un método práctico readLine (), que puede leer directamente una línea. BufferWriter proporciona newLine () Puede escribir nuevas líneas.
4.1 Utilice el flujo del búfer de bytes para transformar el código de copia de archivos
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:/SOFT/CentOS-7-x86_64-Minimal-2009.zip"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:/centos.zip"));
byte[] arr = new byte[1024];
int len = 0;
while ( (len = bis.read(arr)) != -1 ){
bos.write(arr,0,len);//将 arr 数组中的内容从0的位置到len的位置 放到bos中
}
bis.close();
bos.close();
Puede llamar explícitamente a Flush. El significado de Flush es actualizar el búfer, es decir, escribir los datos en el búfer en el disco y ya no colocarlos en la memoria. Al ejecutar os.close (), en realidad se ejecuta os. por defecto.flush(), podemos llamarlo sin una llamada explícita aquí
4.2 Utilice una secuencia de búfer de caracteres para transformar el código de copia de archivos
BufferedReader r = new BufferedReader(new FileReader("d:/abc/a.txt"));
BufferedWriter w = new BufferedWriter(new FileWriter("d:/abc/b.txt"));
String line = null;
while( (line = r.readLine()) != null ){
w.write(line+"\n");
}
r.close();
w.close();
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Example {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
String line; // 用于存储读取的每一行内容的变量
// 循环读取input.txt文件中的每一行内容,直到读取到文件末尾为止
while ((line = reader.readLine()) != null) {
writer.write(line); // 将读取到的内容写入output.txt文件
writer.newLine(); // 写入换行符
}
} catch (IOException e) {
e.printStackTrace(); // 异常处理,打印出错信息
}
}
}