Operación 47-IO en profundidad

Operación IO en profundidad

Codificación de caracteres

  En el mundo de la informática, solo se reconocen los datos de 0 y 1. Si desea describir la codificación de algunos caracteres, debe combinar estos datos binarios, de modo que pueda ver el chino ahora, pero debe mostrarlos correctamente al codificar El contenido debe ser decodificado, por lo que la codificación y la decodificación deben adoptar el mismo conjunto de estándares unificados, si no están unificados, aparecerán códigos confusos.
  En la práctica, los códigos de uso común en desarrollo son los siguientes:

  • GBK / GB2312: Código estándar nacional, que puede describir información en chino. GB2312 solo describe chino simplificado, mientras que GBK incluye simplificado y tradicional;
  • ISO8859-1: Código universal internacional, que se puede utilizar para describir toda la información de letras, si es un pictograma, debe codificarse;
  • Código UNICODE: Se almacena en formato hexadecimal, que puede describir todos los caracteres;
  • Codificación UTF: la parte del pictograma usa codificación hexadecimal, mientras que las letras ordinarias usan codificación ISO8859-1, que tiene la ventaja de una transmisión rápida y ahorro de ancho de banda, que se ha convertido en la primera codificación ("UTF-8") en desarrollo.

  Si desea conocer las reglas de codificación admitidas en el sistema actual, puede utilizar el siguiente código para enumerar todos los atributos nativos:
Enumere los atributos nativos

public class Char_Encode {
    
    

	public static void main(String[] args) {
    
    
		System.getProperties().list(System.out);
	}
}

  Cuando la codificación no está configurada, se usa la codificación predeterminada y la codificación se puede especificar por la fuerza.

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class Char_Encode {
    
    

	public static void main(String[] args) throws Exception {
    
    
		OutputStream output = new FileOutputStream("C:"+File.separator+"mld.txt");
		output.write("中国人民万岁".getBytes("ISO8859-1"));		//指定编码
	}
}

  El problema de los caracteres confusos en el proyecto es la inconsistencia de los estándares de codificación y decodificación, y la mejor manera de resolver caracteres confusos es usar "UTF-8" para todos los métodos de codificación.

Flujo de operación de memoria

  Todos los usados ​​antes son flujos de operaciones de archivos. Con las características de las operaciones de archivos, el programa usa InputStream para leer el contenido del archivo, y luego el programa usa OutputStream para enviar el contenido al archivo. Todas las operaciones se basan en el programa como el Terminal.
ynCVoT.png

  Suponiendo que las operaciones de E / S deben implementarse ahora, pero no desea generar archivos (archivos temporales), puede usar la memoria como terminal para la salida. El proceso   en este momento es el siguiente: Proporcione dos tipos de flujos de operaciones de memoria en Java:
ynCnW4.png

  • Secuencia de operaciones de memoria de bytes: ByteArrayOutputStream (OutputStream 子 类) 、 ByteArrayInputStream (Subclase InputStream
  • Flujo de operaciones de memoria de caracteres: CharArrayWriter, CharArrayReader

  El análisis del uso de memoria se basa principalmente en las clases ByteArrayOutputStream y ByteArrayInputStream:

  • Método de construcción ByteArrayOutputStream:public ByteArrayOutputStream();
  • Método de construcción ByteArrayInputStream:public ByteArrayInputStream(byte[] buf);

Hay un método importante en la clase ByteArrayOutputStream, este método puede obtener toda la información de datos almacenada en el flujo de memoria:

  • recuperar datos:public byte[] toByteArray();
  • Utilice la forma de cadena para obtener:public String toString();

Utilice el tiempo de flujo de memoria para convertir letras minúsculas en letras mayúsculas

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Memory_IO {
    
    

	public static void main(String[] args) throws Exception {
    
    
		String str = "test!";
		InputStream input = new ByteArrayInputStream(str.getBytes());		//将数据保存在内存流
		OutputStream output = new ByteArrayOutputStream();
		int data = 0;
		while((data = input.read()) != -1) {
    
    		//每次读取一个字节
			output.write(Character.toUpperCase((char)data));
		}
		System.out.println(output);
		input.close();
		output.close();
	}
}

  Si no desea simplemente regresar en forma de cadena, porque el almacenamiento puede ser otros datos binarios, entonces puede usar la función extendida de la subclase ByteArrayOutputStream para obtener todos los datos en este momento.
Obtener todos los datos de bytes

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Memory_IO {
    
    

	public static void main(String[] args) throws Exception {
    
    
		String str = "test!";
		InputStream input = new ByteArrayInputStream(str.getBytes());		//将数据保存在内存流
		// 必须使用子类来调用子类自己的扩展方法
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		int data = 0;
		while((data = input.read()) != -1) {
    
    		//每次读取一个字节
			output.write(Character.toUpperCase((char)data));
		}
		byte result[] = output.toByteArray();		//获取全部数据
		System.out.println(new String(result));		//自己处理字节数据
		input.close();
		output.close();
	}
}

  Al principio, ByteArrayOutputStream se puede utilizar para leer archivos de texto a gran escala.

Flujo de tubería

  La función principal del flujo de canalización es implementar operaciones de E / S entre dos subprocesos.   Para el flujo de la tubería, también se divide en dos categorías:
yn18Fe.png

  • Flujo de tubería de caracteres: PipedWriter (Subclase de escritor) 、 PipedReader (Subclase de lector)
    • Procesamiento de conexión:public void connect(PipedInputStream snk) throws IOException
  • Flujo de canalización de bytes: PipedOutputStream (OutputStream 子 类) 、 PipedInputStream (Subclase InputStream)
    • Procesamiento de conexión:public void connect(PipedReader snk) throws IOException

Implementar procesamiento de canalizaciones

//代码有问题
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

class SendThread implements Runnable{
    
    
	private PipedOutputStream output;		//管道输出流
	public SendThread() {
    
    
		this.output = new PipedOutputStream();		//实例化管道输出流
	}
	@Override
	public void run() {
    
    
		for(int x=0; x<10;x++) {
    
    
			try {
    
    		//利用管道实现数据发送处理
				this.output.write(("No:"+(x+1)+"-"+Thread.currentThread().getName()+"信息发送\n").getBytes());
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
			try {
    
    
				this.output.close();
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}
	public PipedOutputStream getOutput() {
    
    
		return output;
	}
}

class ReceiveThread implements Runnable{
    
    
	private PipedInputStream input;
	public ReceiveThread() {
    
    
		this.input = new PipedInputStream();
	}
	@Override
	public void run() {
    
    
		byte data[] = new byte[1024];
		int len = 0;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();		//将所有数据保存到内存输出流
		try {
    
    
			while((len = this.input.read(data)) != -1) {
    
    
				bos.write(data,0,len);		//所有数据保存到内存流bos
			}
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}
		System.out.println("{"+ Thread.currentThread().getName() +"接收消息}" + new String(bos.toByteArray()));
		try {
    
    
			this.input.close();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}
	}
	public PipedInputStream getInput() {
    
    
		return input;
	}
}

public class Piped_IO {
    
    

	public static void main(String[] args) throws IOException {
    
    
		SendThread send = new SendThread();
		ReceiveThread receive = new ReceiveThread();
		send.getOutput().connect(receive.getInput());		//进行管道连接
		new Thread(send,"发送线程").start();
		new Thread(receive,"接收线程").start();
	}
}

  La tubería es similar al efecto de goteo en el hospital, uno es responsable de enviar y el otro es responsable de recibir, y el medio está conectado por la tubería.

RandomAccessFile (clase de lectura aleatoria)

  La operación de procesamiento del contenido del archivo se realiza principalmente a través de InputStream (Reader), OutputStream (Writer), pero la lectura de contenido implementada por estas clases solo puede leer la parte de datos. Si existe tal requisito
  ahora : ahora Un archivo muy grande , si lo lee y analiza de acuerdo con la operación IO tradicional en este momento, es imposible completarlo. Por lo tanto, en este caso, se proporciona una clase RandomAccessFile en el paquete java.io, que puede realizar el archivoSaltar lectura, Puedes leer el archivoParte(Requisito previo: Debe haber una forma de almacenamiento perfecta, es decir, se debe determinar el número de bits de almacenamiento de datos). Los
  siguientes métodos de operación se definen en la clase RandomAccessFile:

  • Método de construcción:public RandomAccessFile(File file,String mode) throws FileNotFoundException;
    • Modo de procesamiento: r, rw

Realice el guardado de archivos

import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;

public class Random_AccessFile {
    
    

	public static void main(String[] args) throws Exception {
    
    
		File file = new File("C:\\Project\\Java_study\\src\\文件\\test.txt");
		RandomAccessFile raf = new RandomAccessFile(file, "rw");
		String names[] = new String[] {
    
    "zhangsan","wangwu  ","lisi    "};
		int ages[] = new int[] {
    
    30,16,20};
		for(int x=0;x<names.length;x++) {
    
    
			raf.write(names[x].getBytes());
			raf.writeInt(ages[x]);
		}
		raf.close();
	}
}

  La característica más importante de RandomAccessFile radica en el procesamiento de la lectura de datos. Debido a que todos los datos se almacenan en una longitud fija, se pueden leer omitiendo bytes al leer:

  • Bajar de un salto:public int skipBytes(int n) throws IOException;
  • Saltar atrás:public void seek(long pos) throws IOException;

Leer datos

import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;

public class Random_AccessFile {
    
    

	public static void main(String[] args) throws Exception {
    
    
		File file = new File("C:\\Project\\Java_study\\src\\文件\\test.txt");
		RandomAccessFile raf = new RandomAccessFile(file, "rw");
		//跳过24位
		{
    
    
		raf.skipBytes(24);
		byte data[] = new byte[8];
		int len = raf.read(data);
		System.out.println(new String(data,0,len) + " - " + raf.readInt());
		}
		//回
		{
    
    
		raf.seek(0);		//回到顶点
		byte data[] = new byte[8];
		int len = raf.read(data);
		System.out.println(new String(data,0,len) + " - " + raf.readInt());
		}
		raf.close();
	}
}

  En el uso general, el usuario define la ubicación que debe leer él mismo y luego lee los datos de acuerdo con la estructura especificada.

Supongo que te gusta

Origin blog.csdn.net/MARVEL_3000/article/details/114435620
Recomendado
Clasificación