Flujo de notas de estudio de C #

Todo el trabajo de entrada y salida realizado en .NET Framework debe utilizar secuencias. Un flujo es una representación abstracta de un dispositivo en serie. Los dispositivos de serialización pueden almacenar datos de forma lineal y se puede acceder a ellos de la misma manera: un byte a la vez.
Hay dos tipos de transmisiones:

  • Flujo de salida: al escribir datos en algún destino externo, es necesario utilizar el flujo de salida. Puede ser un archivo de disco físico, una ubicación de red, una impresora u otro programa.
  • Flujo de entrada: se utiliza para leer datos en la memoria o variables accesibles por el programa. Hasta ahora, la forma más común de flujo de entrada que hemos utilizado es el teclado.
    Las interfaces y clases relacionadas de la secuencia se encuentran principalmente en el System.IOespacio de nombres, donde la Streamclase es una clase abstracta y tiene tres subclases importantes para diferentes objetos de acceso: la FileStreamclase representa las operaciones de archivo, MemoryStreamrepresenta las operaciones de memoria y la BufferedStreamclase representa el procesamiento del búfer.

Clase 1.Stream

La Streamclase abstracta contiene muchos atributos y métodos necesarios en el flujo, como se muestra en la siguiente tabla:
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Estos atributos y métodos involucran todos los aspectos de la lectura y escritura del flujo. Los 4 métodos de operaciones de lectura y escritura son los siguientes:

	int ReadByte();
	int Read(byte[] array, int offset, int count);
	void WriteByte(byte value);
	void Write(byte[] array, int offset, int count);

Entre ellos ReadByte(), los bytes leídos se convierten en números enteros y se devuelven. Si no se leen bytes, se devuelve -1. Read()El método devuelve el número de bytes leídos.
Por BeginRead(), EndRead(), BeginWrite()y EndWrie()por el estilo, clase Stream puede apoyar las operaciones de E / S asíncrona.
Seek()Método significa ubicar el puntero de búsqueda en la secuencia para determinar la posición de la siguiente operación de lectura o escritura. En una secuencia de este tipo, su CanSeekvalor de atributo es true, y su Seek()método se puede utilizar para establecer la posición del puntero. Seek()El método requiere dos parámetros: uno se usa para indicar el valor del movimiento del puntero de búsqueda y el otro se usa para determinar la posición de referencia del movimiento del puntero. La posición de referencia es SeekOriginel miembro de enumeración, que puede ser una de las siguientes tres situaciones:

  • SeekOrigin.Begin(el comienzo del archivo);
  • SeekOrigin.Current(La posición actual del puntero en el archivo);
  • SeekOrigin.End(Fin de archivo).
    El siguiente código muestra cómo buscar en un archivo:
	aStream.Seek(200, SeekOrigin.Begin);	// 从开头移到200位置
	aStream.Seek(0, SeekOrigin.End);		// 移到文件尾
	aStream.Seek(-20, SeekOrigin.Current);	// 从当前位置反向移动20

2.Clase FileStream

FileStreamSe Streamderiva directamente de ella. FileStreamLos objetos pueden leer contenido de archivos o escribir contenido en archivos y pueden manejar bytes, caracteres, cadenas y otros tipos de datos. Este objeto también se puede utilizar para realizar una entrada / salida estándar y una salida de error estándar.
Cabe señalar que el FileStreamobjeto generalmente no se usa solo, porque su aplicación está más cerca de la capa inferior. Este objeto solo puede leer y escribir bytes, por lo que al usarlo, debe convertir cadenas, números y objetos en bytes antes de que se le puedan pasar FileStream. En vista de esto, FileStreamgeneralmente se empaqueta en algunas otras clases para su uso, como BinaryWritero TextReader, estas clases pueden manejar estructuras de datos de alto nivel. La clase FileStream tiene muchas formas de métodos de construcción, por lo que se pueden usar diferentes métodos de construcción de acuerdo con diferentes combinaciones de los siguientes parámetros FileStream:

  • ① Nombre de archivo;
  • ② Identificador de archivo: un número entero utilizado para representar el identificador de archivo;
  • ③ Modo de acceso: uno de los valores de enumeración de FileMode;
  • ④ Permisos de lectura / escritura: uno de los valores de enumeración de FileAccess;
  • ⑤ Modo de uso compartido: uno de los valores de enumeración de FileShare;
  • ⑥ Tamaño del búfer.

La Tabla 6-3, la Tabla 6-4 y la Tabla 6-5 describen respectivamente los modos de acceso a archivos, los permisos de acceso y los modos de uso compartido.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Por ejemplo, para crear un archivo y hacer que el archivo admita operaciones de lectura compartida:

	FileStream fs = new FileStream(@"c:\temp\foo.txt", FileMode.Create, FileAccess.Reead);

FIleStreamPuede ser una forma síncrona o asincrónica de crear, al mismo tiempo, además de la Streamadición de la propiedad heredada, pero también aumentar la IsAsyncpropiedad. Además, el método enumerado en la siguiente tabla se agrega a esta clase: El
Inserte la descripción de la imagen aquí
GetHandle()método puede devolver un ReadFile()identificador que se puede usar en la función del sistema operativo nativo (como en Win32 ), pero este método debe usarse con precaución. Si usa el identificador de archivo para realizar algunos cambios en el archivo subyacente y luego intenta usar el archivo FileStream, puede dañar los datos en el archivo.
FileStreamDurante el funcionamiento de la clase, se pueden generar las siguientes excepciones:

  • ① ArgumentException: la ruta es un carácter nulo
  • ② ArgumentNullException: la ruta es una referencia nula
  • ③ SecurityException: no hay autoridad de operación en el archivo
  • ④ FileNotFoundException-archivo no encontrado
  • ⑤ IOException: se han producido otros errores de E / S, como especificar un controlador incorrecto
  • ⑥ DirectoryNotFoundException —— El directorio no existe

Por ejemplo, FileStreampara leer y escribir el contenido del archivo:

using System;
using System.IO;
class Test
{
    
    
	static void Main(){
    
    
		try {
    
    
		FileStream fsw = new FileStream("test.dat", FileMode.Create, FileAccess.Write);

			// Wirte some data to the stream
			fsw.WriteByte(33);
			fsw.Write(new byte[] {
    
     34, 35, 36 }, 0, 3);
			fsw.Close();

			FileStream fsr = new FileStream("test.dat", FileMode.Open, FileAccess.Read);
			Console.WriteLine(fsr.ReadByte());
			Console.WriteLine(fsr.ReadByte());
			Console.WriteLine(fsr.ReadByte());
			Console.WriteLine(fsr.ReadByte());
		} catch (Exception e) {
    
    
			Console.WriteLine("Exception:" + e.ToString());
		}
	}
}

resultado de la operación:
Inserte la descripción de la imagen aquí

3.ClaseMemoryStream

MemoryStreamDe la clase también Streamheredada, se usa la memoria en lugar del archivo para almacenar la secuencia directamente, pero se trata de algo FileStreammuy similar. MemoryStreamLos datos se almacenan en la memoria en forma de una matriz de bytes y se pueden usar para reemplazar la función de los archivos temporales en la aplicación.
Al igual que con el FileStreammismo, MemoryStreamexisten muchos métodos de construcción. Los dos siguientes se utilizan con más frecuencia:

	MemoryStream();
	MemoryStream(byte []);

Utilice el primer método de construcción aquí para establecer MemoryStreamque cuando los datos se escriben al final de la secuencia, se MemoryStreampueden expandir en consecuencia. El segundo método de construcción crea una MemoryStreamnueva instancia de la clase basada en la matriz de bytes especificada , de modo que no se puede cambiar el tamaño de la secuencia creada.
Además de las Streampropiedades heredadas, MemoryStreamse ha agregado una propiedad adicional Capacity. CapacityEl atributo se puede utilizar para indicar el número de bytes asignados actualmente al flujo. Este atributo es muy útil cuando se utilizan flujos basados ​​en matrices de bytes, porque este atributo puede indicar el tamaño de la matriz y el Lengthatributo puede indicar el número de bytes que se utilizan actualmente.
MemoryStreamNo es posible realizar métodos de lectura / escritura asíncronos porque esta función no es necesaria para la E / S de memoria. Pero el objeto puede realizar los siguientes tres métodos adicionales.

  • ① —— GetBuffer()Devuelve una referencia a la matriz de bytes en la secuencia
  • ② ——Escribe ToArray()todo el contenido en la matriz de bytes
  • ③ ——Escribir WriteTo()el contenido de la transmisión en otra transmisión

Por ejemplo, use MemoryStream para operar en la memoria:

using System;
using System.IO;
class Test
{
    
    
	static void Main(){
    
    
		try {
    
    
			byte[] ary = {
    
     33, 34, 35, 36, 37 };
			int b;

			MemoryStream msr = new MemoryStream(ary);
			MemoryStream msw = new MemoryStream();

			while ((b = msr.ReadByte()) != -1) {
    
    
				msw.WriteByte((byte)(b + 3));
			}
			byte[] result = msw.ToArray();

			foreach (byte bt in result)
				Console.WriteLine(bt);

		} catch (Exception e) {
    
    
			Console.WriteLine("Exception:" + e.ToString());
		}
	}
}

resultado de la operación:
Inserte la descripción de la imagen aquí

4.BufferedStrea 类

BufferedStreamPuede mejorar la eficiencia de ejecución de las operaciones de lectura y escritura, porque esta clase puede almacenar datos en caché en la memoria, reduciendo así el número de llamadas al sistema operativo. BufferedStreamNo se puede usar solo, sino que se debe empaquetar en algunos otros tipos de flujos, especialmente los tipos BinaryWritery BinaryReadertipos que se describen a continuación . Además, también es común almacenar en caché y envolver el flujo de red (NetworkStream). Para la operación de BinaryStreamllamada Flush(), el contenido almacenado en caché se puede escribir en la secuencia.

Supongo que te gusta

Origin blog.csdn.net/qq_45349225/article/details/114373805
Recomendado
Clasificación