En el campo de la informática y la tecnología de la información, I/Oeste término significa entrada/salida (en inglés: Input/Output), generalmente se refiere a la entrada y salida de datos entre la memoria (interna y externa) u otros dispositivos periféricos, es el sistema de procesamiento de información y Comunicación externa. Las entradas son las señales o datos recibidos por el sistema, y ​​las salidas son las señales o datos enviados desde él.

I/OHay muchas bibliotecas integradas involucradas en las operaciones en el lenguaje Go , como: iobiblioteca, osbiblioteca, ioutilbiblioteca, bufiobiblioteca, bytesbiblioteca , biblioteca, stringsetc. Es bueno tener tantas bibliotecas integradas, pero I/O¿qué biblioteca deberíamos elegir cuando se trata de los escenarios involucrados?

io.Lector/Escritor

Vaya usos del lenguaje io.Readery io.Writerdos interfaces para abstraerse I/O, sus definiciones son las siguientes.

type Reader interface {
 Read(p []byte) (n int, err error)
}

type Writer interface {
 Write(p []byte) (n int, err error)
}

io.ReaderUna interfaz representa una entidad desde la que se puede leer un flujo de bytes y una entidad en la que io.Writerse puede escribir un flujo de bytes.

Varias implementaciones de uso común de io.Reader/Writer

  • net.Conn: representa una conexión de red.
  • os.Stdin, os.Stdout, os.Stderr: Entrada, salida y error estándar.
  • os.File: red, entrada y salida estándar, lectura de flujo de archivos.
  • strings.Reader: las cadenas se abstraen en una implementación de io.Reader.
  • bytes.Reader: []byte se abstrae en la implementación de io.Reader.
  • bytes.Buffer: []byte se abstrae en la implementación de io.Reader y io.Writer.
  • bufio.Reader/Writer: lectura y escritura de secuencias almacenadas en búfer (por ejemplo, línea por línea).

Además de estas implementaciones, la ioutilbiblioteca de herramientas contiene muchas funciones de herramientas IO, y la biblioteca integrada relacionada con la codificación encoding/base64, encoding/binaryetc. también realiza sus respectivas funciones de codificación a través de io.Reader e io.Writer.

La relación entre estas implementaciones comunes y bibliotecas de herramientas e io.Reader e io.Writer se puede representar mediante el siguiente diagrama.

imagen

Escenarios de uso para cada biblioteca de E/S

biblioteca io

ioLas bibliotecas pertenecen a la biblioteca de definición de interfaz subyacente. Su función principal es definir I/Ointerfaces básicas y constantes básicas, y explicar las funciones de estas interfaces. Cuando se escribe código para realizar I/Ooperaciones, esta biblioteca generalmente solo se usa para llamar a sus constantes y definiciones de interfaz, como para io.EOFjuzgar si se ha leído y usarla io.Readercomo declaración de tipo de variables.

// 字节流读取完后,会返回io.EOF这个error
for {
 n, err := r.Read(buf)
 fmt.Println(n, err, buf[:n])
 if err == io.EOF {
  break
 }
}

biblioteca del sistema operativo

osLa biblioteca se ocupa principalmente del funcionamiento del sistema operativo y actúa como un puente para la interacción entre el programa Go y el sistema operativo. Las operaciones de creación de archivos, apertura o cierre de archivos, sockets, etc. están todas ligadas al sistema operativo, por lo que todas se osrealizan a través de librerías. Esta biblioteca se usa a menudo junto con ioutil, bufioetc.

biblioteca ioutil

ioutilLa biblioteca es un conjunto de herramientas que proporciona muchas funciones útiles de herramientas de E/S, como ReadAll, ReadFile, WriteFile, ReadDir. Lo único que debe tener en cuenta es que todos son de lectura y escritura únicas, por lo que debe prestar atención al tamaño del archivo cuando lo usa, especialmente cuando lee datos del archivo a la memoria al mismo tiempo.

Leer todo en el archivo

func readByFile() {
  data, err := ioutil.ReadFile( "./file/test.txt")
  if err != nil {
    log.Fatal("err:", err)
    return
  }
  fmt.Println("data"string(data)) 
}

Escribir datos en el archivo a la vez

func writeFile() {
  err := ioutil.WriteFile("./file/write_test.txt", []byte("hello world!"), 0644)
  if err != nil {
    panic(err)
    return
  }
}

biblioteca bufio

bufio, que puede entenderse como iouna capa de caché adicional sobre la base de la biblioteca, proporciona muchas funciones para leer y escribir por línea, desde leer y escribir byte por byte en la biblioteca io hasta leer y escribir línea por línea Para escribir código Todavía mucho más conveniente.


func readBigFile(filePath string) error {
  f, err := os.Open(filePath)
  defer f.Close()

  if err != nil {
    log.Fatal(err)
    return err
  }

  buf := bufio.NewReader(f)
  count := 0
  // 循环中打印前100行内容
  for {
    count += 1
    line, err := buf.ReadString('\n')
    line = strings.TrimSpace(line)
    if err != nil {
      return err
    }
    fmt.Println("line", line)

    if count > 100 {
      break
    }
  }
  return nil
}
  • Métodos ReadLine y ReadString: buf.ReadLine(), buf.ReadString("\n") se leen todos por línea, pero ReadLine lee []byte, que lee la cadena directamente, y finalmente llaman a la capa inferior Ambos son métodos ReadSlice .
  • Biblioteca bufio VS ioutil: tanto la biblioteca bufio como la ioutil brindan la capacidad de leer y escribir archivos. La única diferencia entre ellos es que bufio tiene una capa adicional de almacenamiento en caché. Esta ventaja se refleja principalmente al leer archivos grandes.

biblioteca de bytes y cadenas

Bytes.Reader y string.Reader en las bibliotecas de bytes y cadenas implementan la io.Readerinterfaz y también proporcionan el método NewReader para construir directamente la implementación de Reader correspondiente a partir de una variable de tipo []byteo tipo.string

r := strings.NewReader("abcde")
// 或者是 bytes.NewReader([]byte("abcde"))
buf := make([]byte4)
for {
 n, err := r.Read(buf)
 fmt.Println(n, err, buf[:n])
 if err == io.EOF {
  break
 }
}

Otra diferencia es que la biblioteca de bytes tiene la funcionalidad de búfer, mientras que la biblioteca de cadenas no.

var buf bytes.Buffer
fmt.Fprintf(&buf, "Size: %d MB."85)
s := buf.String()) // s == "Size: 85 MB."

Resumir

En cuanto a io.Readerla io.Writerinterfaz, puede entenderse simplemente como fuente de lectura y fuente de escritura. Es decir, siempre que se implemente Readerel Readmétodo in, esta cosa se puede usar como una fuente de lectura, que puede contener datos y ser leída por nosotros. Writertambién es así.

I/OLo anterior es un resumen de los escenarios de uso y los problemas que debe resolver cada biblioteca de las bibliotecas integradas del lenguaje Go que uso a menudo cuando realizo operaciones en el lenguaje Go. Espero que pueda ayudarlo a aclarar sus ideas. referencia, en la tarea de desarrollo Seleccione correctamente la biblioteca adecuada cuando sea necesario para completar la I/Ooperación. Si la descripción en el artículo es incorrecta, deje un mensaje para corregirlo, y también puede discutir y hacer sugerencias sobre el contenido del artículo en el mensaje.

Lectura recomendada: