cpp

Структура Reader: чтение из файла

Структура bufio.Reader содержит методы для чтения из файла. При этом используется буфер, что позволяет, например, читать файл построчно. Создать объект структуры bufio.Reader можно с помощью следующих функций из пакета bufio:

  • NewReader() — формат функции:
bufio.NewReader(rd io.Reader) *bufio.Reader

Пример чтения первой строки (фрагмента до первого символа \n):

buf := strings.NewReader("Строка1\r\nСтрока2\nСтрока3")
reader := bufio.NewReader(buf)
fmt.Println(reader.Size()) // 4096
line, isPrefix, err := reader.ReadLine()
fmt.Printf("%q\n", line)   // "Строка1"
fmt.Println(isPrefix, err) // false <nil>
  • NewReaderSize() — позволяет дополнительно указать размер буфера. Формат функции:
bufio.NewReaderSize(rd io.Reader, size int) *bufio.Reader

Пример построчного чтения из файла (обратите внимание: для построчного чтения файла лучше использовать структуру bufio.Scanner (см. разд. 14.13), а не структуру bufio.Reader):

func test() {
   file, err := os.Open(`C:\book\file.txt`)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer file.Close()
   reader := bufio.NewReaderSize(file, 65536)
   fmt.Println(reader.Size()) // 65536
   for line, isPrefix, err := reader.ReadLine(); err != io.EOF; {
      if err != nil {
         fmt.Println(err)
         return
      }
      if isPrefix {
         fmt.Println("isPrefix =", isPrefix)
         return
      }
      fmt.Printf("%q\n", line)
      line, isPrefix, err = reader.ReadLine()
   }
}

Результат (символы \r и \n удаляются):

65536
"Строка1"
"Строка2"

Структура bufio.Reader содержит следующие методы:

  • Read() — считывает из потока максимум len(b) байтов или оставшиеся байты и записывает их в байтовый слайс b. Значение n может быть меньше, чем len(b). Формат метода Read():
(*bufio.Reader).Read(b []byte) (n int, err error)

Метод возвращает два значения. Через первое значение доступно число считанных байтов. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. В конце файла возвращается 0, io.EOF. Пример чтения всего содержимого потока:

buf := strings.NewReader("String1\nString2\nString3")
reader := bufio.NewReader(buf)
b := make([]byte, 16)
for {
   n, err := reader.Read(b)
   if err != nil {
      if err != io.EOF {
         fmt.Println(err)
         return
      }
      break
   }
   fmt.Print(string(b[0:n]))
}
  • ReadByte() — при каждом вызове через первое возвращаемое значение доступен следующий байт. Через второе возвращаемое значение можно получить информацию об ошибке. Если в потоке больше нет данных, то значением будет io.EOF. Если ошибки не возникло, то значением будет nil. Формат метода:
(*bufio.Reader).ReadByte() (byte, error)

Пример:

buf := strings.NewReader("a")
reader := bufio.NewReader(buf)
fmt.Println(reader.ReadByte()) // 97 <nil>
fmt.Println(reader.ReadByte()) // 0 EOF
  • UnreadByte() — отменяет чтение последнего байта. Формат метода:
(*bufio.Reader).UnreadByte() error

Пример:

buf := strings.NewReader("a")
reader := bufio.NewReader(buf)
fmt.Println(reader.ReadByte())   // 97 <nil>
fmt.Println(reader.UnreadByte()) // <nil>
fmt.Println(reader.ReadByte())   // 97 <nil>
  • ReadRune() — при каждом вызове через первое возвращаемое значение доступен следующий символ. Через второе возвращаемое значение доступно число байтов. Через третье возвращаемое значение можно получить информацию об ошибке. Если в потоке больше нет данных, то значением будет io.EOF. Если ошибки не возникло, то значением будет nil. Формат метода:
(*bufio.Reader).ReadRune() (r rune, size int, err error)

Пример:

buf := strings.NewReader("a")
reader := bufio.NewReader(buf)
fmt.Println(reader.ReadRune()) // 97 1 <nil>
fmt.Println(reader.ReadRune()) // 0 0 EOF
  • UnreadRune() — отменяет чтение последнего символа. Формат метода:
(*bufio.Reader).UnreadRune() error

Пример:

buf := strings.NewReader("a")
reader := bufio.NewReader(buf)
fmt.Println(reader.ReadRune())   // 97 1 <nil>
fmt.Println(reader.UnreadRune()) // <nil>
fmt.Println(reader.ReadRune())   // 97 1 <nil>
  • WriteTo() — считывает все содержимое потока ввода и отправляет его в поток вывода w. Формат метода:
(*bufio.Reader).WriteTo(w io.Writer) (n int64, err error)

Через переменную n доступно число записанных байтов, а через переменную err — описание ошибки. Пример записи в стандартный поток вывода os.Stdout:

buf := strings.NewReader("test тест ")
reader := bufio.NewReader(buf)
fmt.Println(reader.WriteTo(os.Stdout)) // test тест 14 <nil>
  • ReadString() — считывает данные из потока до нахождения разделителя delim и возвращает значение в виде строки через первое значение. Разделитель входит в состав возвращаемого значения. Через второе возвращаемое значение можно получить информацию об ошибке. Если в потоке больше нет данных или разделитель delim не найден, то значением будет io.EOF. Если ошибки не возникло, то значением будет nil. Формат метода:
(*bufio.Reader).ReadString(delim byte) (string, error)

Пример:

buf := strings.NewReader("Строка1\nСтрока2")
reader := bufio.NewReader(buf)
line, err := reader.ReadString('\n')
fmt.Printf("%q\n", line) // "Строка1\n"
fmt.Println(err)         // <nil>
line, err = reader.ReadString('\n')
fmt.Printf("%q\n", line) // "Строка2"
fmt.Println(err)         // EOF
line, err = reader.ReadString('\n')
fmt.Printf("%q\n", line) // ""
fmt.Println(err)         // EOF
  • ReadBytes() — считывает данные из потока до нахождения разделителя delim и возвращает значение в виде байтового слайса через первое значение. Разделитель входит в состав возвращаемого значения. Через второе возвращаемое значение можно получить информацию об ошибке. Если в потоке больше нет данных или разделитель delim не найден, то значением будет io.EOF. Если ошибки не возникло, то значением будет nil. Формат метода:
(*bufio.Reader).ReadBytes(delim byte) ([]byte, error)

Пример:

buf := strings.NewReader("Строка1\nСтрока2")
reader := bufio.NewReader(buf)
line, err := reader.ReadBytes('\n')
fmt.Printf("%q\n", line) // "Строка1\n"
fmt.Println(err)         // <nil>
line, err = reader.ReadBytes('\n')
fmt.Printf("%q\n", line) // "Строка2"
fmt.Println(err)         // EOF
line, err = reader.ReadBytes('\n')
fmt.Printf("%q\n", line) // ""
fmt.Println(err)         // EOF
  • ReadSlice() — считывает данные из потока до нахождения разделителя delim и возвращает значение в виде байтового среза через первое значение. Разделитель входит в состав возвращаемого значения. Обратите внимание: данные будут перезаписаны при следующей операции чтения. Если нужно избежать перезаписи, то следует воспользоваться методом ReadString() или ReadBytes(). Через второе возвращаемое значение можно получить информацию об ошибке. Если в потоке больше нет данных или разделитель delim не найден, то значением будет io.EOF. Если ошибки не возникло, то значением будет nil. Формат метода:
(*bufio.Reader).ReadSlice(delim byte) (line []byte, err error)

Пример:

buf := strings.NewReader("Строка1\nСтрока2")
reader := bufio.NewReader(buf)
line, err := reader.ReadSlice('\n')
fmt.Printf("%q\n", line) // "Строка1\n"
fmt.Println(err)         // <nil>
line, err = reader.ReadSlice('\n')
fmt.Printf("%q\n", line) // "Строка2"
fmt.Println(err)         // EOF
line, err = reader.ReadSlice('\n')
fmt.Printf("%q\n", line) // ""
fmt.Println(err)         // EOF
  • ReadLine() — считывает данные из потока до нахождения символа перевода строки и возвращает значение в виде байтового среза через первое значение. При этом символы \r\n и \n не входят в состав возвращаемого значения. Обратите внимание: данные будут перезаписаны при следующей операции чтения. Через второе возвращаемое значение доступно значение false, если строка получена полностью. Если строка слишком длинная для буфера, то возвращается часть строки, поместившаяся в буфер, и второе значение устанавливается равным true. Оставшаяся часть строки становится доступной при следующей операции чтения. Через третье возвращаемое значение можно получить информацию об ошибке. Если в потоке больше нет данных, то значением будет io.EOF. Если ошибки не возникло, то значением будет nil. Формат метода:
(*bufio.Reader).ReadLine() (line []byte, isPrefix bool,
                            err error)

Пример построчного чтения из потока (обратите внимание: для построчного чтения файла лучше использовать структуру bufio.Scanner (см. разд. 14.13), а не структуру bufio.Reader):

buf := strings.NewReader("Строка1\r\nСтрока23456789")
reader := bufio.NewReaderSize(buf, 16)
fmt.Println(reader.Size()) // 16
line, isPrefix, err := reader.ReadLine()
fmt.Printf("%q\n", line)   // "Строка1"
fmt.Println(isPrefix, err) // false <nil>
line, isPrefix, err = reader.ReadLine()
// Строка не поместилась целиком!
fmt.Printf("%q\n", line)   // "Строка2345"
fmt.Println(isPrefix, err) // true <nil>
line, isPrefix, err = reader.ReadLine()
fmt.Printf("%q\n", line)   // "6789"
fmt.Println(isPrefix, err) // false <nil>
line, isPrefix, err = reader.ReadLine()
fmt.Printf("%q\n", line)   // ""
fmt.Println(isPrefix, err) // false EOF
  • Peek() — считывает n байтов из потока и возвращает значение в виде байтового среза через первое значение. При этом указатель внутри потока не перемещается. Обратите внимание: данные будут перезаписаны при следующей операции чтения. Через второе возвращаемое значение можно получить информацию об ошибке. Если в потоке больше нет данных, то значением будет io.EOF. Если ошибки не возникло, то значением будет nil. Формат метода:
(*bufio.Reader).Peek(n int) ([]byte, error)

Пример:

buf := strings.NewReader("Строка1\r\nСтрока2")
reader := bufio.NewReaderSize(buf, 16)
b, err := reader.Peek(12)
fmt.Printf("%q\n", b) // "Строка"
fmt.Println(err)      // <nil>
b, err = reader.Peek(12)
fmt.Printf("%q\n", b) // "Строка"
fmt.Println(err)      // <nil>
b, err = reader.Peek(40)
fmt.Printf("%q\n", b) // "Строка1\r\n\xd0"
fmt.Println(err)      // bufio: buffer full
  • Discard() — пропускает n байтов и возвращает количество реально пропущенных байтов через первое значение. Через второе возвращаемое значение можно получить информацию об ошибке. Если в потоке больше нет данных, то значением будет io.EOF. Если ошибки не возникло, то значением будет nil. Формат метода:
(*bufio.Reader).Discard(n int) (discarded int, err error)

Пример:

buf := strings.NewReader("Строка1\r\nСтрока2")
reader := bufio.NewReader(buf)
fmt.Println(reader.Discard(12)) // 12 <nil>
r, _, err := reader.ReadRune()
fmt.Printf("%q\n", r) // '1'
fmt.Println(err)      // <nil>
  • Size() — возвращает размер буфера в байтах. Формат метода:
(*bufio.Reader).Size() int

Пример:

buf := strings.NewReader("Строка1\r\nСтрока2\nСтрока3")
reader := bufio.NewReader(buf)
fmt.Println(reader.Size()) // 4096
  • Buffered() — возвращает количество байтов, которое можно прочитать из буфера. Формат метода:
(*bufio.Reader).Buffered() int

Пример:

buf := strings.NewReader("Строка1\r\nСтрока2\nСтрока3")
reader := bufio.NewReader(buf)
fmt.Println(reader.Buffered()) // 0
line, _, _ := reader.ReadLine()
fmt.Printf("%q\n", line)       // "Строка1"
fmt.Println(reader.Buffered()) // 27
  • Reset() — удаляет содержимое буфера и заменяет поток ввода на r. Формат метода:
(*bufio.Reader).Reset(r io.Reader)

Пример:

buf := strings.NewReader("Строка1\r\nСтрока2\nСтрока3")
buf2 := strings.NewReader("Строка4\nСтрока5")
reader := bufio.NewReader(buf)
line, _, _ := reader.ReadLine()
fmt.Printf("%q\n", line) // "Строка1"
reader.Reset(buf2)
line, _, _ = reader.ReadLine()
fmt.Printf("%q\n", line) // "Строка4"

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp