bufio
는 버퍼링된 I/O 를 구현한다.
io.Reader 또는 io.Writer 객체를 래핑하여 인터페이스를 구현하지만 버퍼링 및 텍스트 I/O 에 대한 도움을 제공하는 다른 개체를 만든다.
const (
// 토큰을 버퍼링하는데 최대 크기
MaxScanTokenSize = 64 * 1024
)
var (
ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
ErrBufferFull = errors.New("bufio: buffer full")
ErrNegativeCount = errors.New("bufio: negative count")
ErrTooLong = errors.New("bufio.Scanner: token too long")
ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
ErrAdvanceTooFar = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
ErrBadReadCount = errors.New("bufio.Scanner: Read returned impossible count")
)
다음은 특수한 감시 오류 값이다.
오류와 함께 전달되는 토큰이 마지막 토큰이고 이 노큰 이후에 스캔이 중지되어야 함을 나타내기 위해 Split 함수에 의해 반환된다.
Scan 에서 ErrFinalToken 을 수신하면 오류없이 검색이 중지된다.
이 값은 처리를 조기에 중지하거나 최종 빈 토큰을 전달해야할 때 유용하다.
var ErrFinalToken = errors.New("final token")
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)
각 바이트를 토큰으로 반환하는 스캐너의 분할 함수이다.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)
후행 줄 끝 마커를 제거하고 각 텍스트 줄을 반환하는 스캐너 용 분할 기능이다.
반환된 줄은 비어있을 수 있다.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)
각 UTF-8로 인코딩된 룬을 토큰으로 반환하는 스캐너의 분할 함수이다.
반환된 룬의 시퀀스는 입력에 대한 범위 루프의 문자열과 동일하다.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)
주변 공백이 삭제된 상태에서 각 공백으로 구분된 텍스트 단어를 반환하는 Scanner 용 분할 기능이다.
빈 문자열을 반환하지 않는다.
type ReadWriter struct {
*Reader
*Writer
}
ReadWriter
는 Reader
와 Writer
에 대한 포인터를 저장한다.
io.ReadWriter 를 구현한다.
func NewReadWriter(r *Reader, w *Writer) *ReadWriter
r
과 w
를 디스패치하는 새로운 ReadWriter 를 할당한다.
type Reader struct {
// 필터링되거나 내보내지지 않은 필드 포함
}
io.Reader 객체에 대한 버퍼링을 구현한다.
func NewReader(rd io.Reader) *Reader
버퍼가 기본 사이즈인 새로운 Reader 를 반환한다.
func NewReaderSize(rd io.Reader, size int) *Reader
버퍼가 지정된 크기 이상인 새 Reader 를 반환한다.
인수 io.Reader 가 이미 충분히 큰 Reader 인 경우 기본 Reader 를 반환한다.
func (b *Reader) Buffered() int
현재 버퍼에서 읽을 수 있는 바이트 수를 반환한다.
func (b *Reader) Discard(n int) (discarded int, err error)
다음 n 바이트를 건너 뛰고 폐기된 바이트 수를 반환한다.
Discard 가 n 바이트 미만을 건너 뛰면 오류도 반환된다.
0 <= n <= b.Buffered()
이면 기본 io.Reader
에서 읽지 않고도 Discard
가 성공할 수 있다.
func (b *Reader) Peek(n int) ([]byte, error)
판독기를 진행하지 않고 다음 n
바이트를 반환한다.
바이트는 다음 읽기 호출에서 유효하지 않고 n
바이트 미만을 반환하면 읽기가 짧은 이유를 설명하는 오류도 반환된다.
n
이 b
버퍼 크기보다 크면 오류는 ErrBufferFull
이다.
func (b *Reader) Read(p []byte) (int, error)
데이터 p
를 읽어 바이트 수를 반환한다.
최대 한 번의 읽기에서 가져오므로 n
은 len(p)
보다 작을 수 있다.
정확시 len(p)
바이트를 읽으려면 io.ReadFull(b, p)
를 사용하자.
EOF 에서 카운트는 0 이 되고 err 은 io.EOF 가 된다.
func (b *Reader) ReadByte() (byte, error)
단일 바이트를 읽고 반환한다.
사용 가능한 바이트가 없으면 오류를 반환한다.
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
입력에서 delim
이 처음 나타날 때까지 읽고 구분 기호까지 포함한 데이터를 포함하는 슬라이스를 반환한다.
구분 기호 찾기 전에 오류가 발생하면 이전에 읽은 데이터와 오류 자체를 반환한다.
delim
으로 끝나지 않는 경우만 err != nil
을 반환한다.
간단한 사용에서는 스캐너가 더 편할 수 있다.
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
낮은 수준의 라인 읽기 기본요소이다. 대부분의 호출자 ReadByte('\n')
또는 ReadString('\n')
을 사용하거나 스캐너를 사용해야 한다.
라인이 버퍼에 비해 너무 길면 isPrefix
가 설정되고 라인의 시작 부분이 반환된다. 나머지 라인은 향후에 반환된다.
라인 마지막 조각을 반환할때는 false
가 된다.
끝에서 반환된 텍스트에는 \r\n \n
는 포함되지 않는다.
func (b *Reader) ReadRune() (r rune, size int, err error)
UTF-8 로 인코딩된 단일 유니 코드 문자를 읽고 룬과 해당 크기를 바이트 단위로 반환한다.
인코딩된 룬이 유효하지 않은 경우 1 바이트를 소비하고 크기가 1 인 unicode.ReplacementChar
를 반환한다.
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
delim
이 처음 나타날 때까지 읽고 버퍼의 바이트를 가리키는 슬라이스를 반환한다. 바이트는 다음 읽기에서 유효하지 않다.
구분 기호를 찾기 전에 오류가 발생하면 버퍼의 모든 데이터와 오류 자체를 반환한다.
버퍼가 delim
없이 채워지면 ErrBufferFull
과 함께 실패한다.
func (b *Reader) ReadString (delim byte) (string ,error)
입력에서 delim
이 처음 나타날 때까지 읽고 구분 기호까지 포함하는 데이터를 포함할 문자열을 반환한다.
구분 기호를 찾기 전에 ReadString 에 오류가 발생하면 이전에 읽은 데이터와 오류 자체를 반환한다.
delim
으로 끝나지 않는 경우에만 err != nil
을 반환한다
간단한 사용엔 스캐너가 더 편리하다.
func (b *Reader) Reset(r io.Reader)
버퍼링된 데이터를 버리고 모든 상태를 재설정하며 판독기를 r
에서 읽도록 전환한다.
func (b *Reader) Size() int
기본 버퍼의 크기를 바이트 단위로 반환한다.
func (b *Reader) UnreadByte() error
마지막 바이트를 읽지 않는다.
가장 최근에 읽은 바이트만 읽지 않을 수도 있다.
func (b *Reader) UnreadRune() error
마지막 룬을 읽지 않는다.
Reader 에서 가장 최근에 호출된 메소드가 ReadRune 이 아닌 경우 UnreadRune 은 오류를 반환한다.
func (b *Reader) WriteTo(w io.Writer) (n int64, err error)
io.WriterTo 를 구현한다.
기본 Reader 의 Read 메소드를 여러번 호출할 수 있다.
type Scanner struct {
// 필터링되거나 내보내지지 않은 필드 포함
}
줄 바꿈으로 구분된 텍스트 파일과 같은 데이터를 읽기 위한 편리한 인터페이스를 제공한다.
Scan 메소드에 대한 연속 호출은 토큰 사이의 바이트를 건너 뛰고 파일의 '토큰' 을 통과한다.
토큰 사양은 SplitFunc
유형의 분할 함수에 의해 정의된다.
스캔은 EOF, 첫 번째 I/O 오류 또는 너무 큰 버퍼라 맞지 않는 토큰에서 복구 불가능하게 중지된다.
오류 처리 또는 큰 토큰에 대한 더 많은 제어가 필요하거나 판독기에서 순차적 스캔을 실행해야하는 프로그램은 bufio.Reader 를 사용하자.
func (s *Scanner) Buffer(buf []byte, max int)
버퍼는 스캔할 때 사용할 초기 버퍼와 스캔 중에 할당할 수 있는 버퍼의 최대 크기를 설정한다.
최대 토큰 크기는 max 및 cap(buf) 보다 크다.
max <= cap(buf)
이면 Scan 은 이 버퍼만 사용하고 할당하지 않는다.
기본적으로 Scan 은 내부 버퍼를 사용하고 최대 토큰 크기를 MaxScanTokenSize 로 설정한다.
스캰 시작 후 호출되면 패닉이 발생한다.
func (s *Scanner) Bytes() []byte
Scan 호출에 의해 생성된 가장 최근 토큰을 반환한다.
기본 배열은 Scan 에 대한 후속 호출에서 덮어 쓸 데이터를 가리킬 수 있다.
func (s *Scanner) Err() error
스캐너에서 발생한 첫 번째 비 EOF 오류를 반환한다.
func (s *Scanner) Scan() bool
스캐너를 다음 토큰으로 진행한 다음 바이트 또는 텍스트 방법을 통해 사용할 수 있다.
입력의 끝에 도달하거나 오류가 발생하여 스캔이 중지되면 false
를 리턴한다.
Scan 이 false
를 반환하면 Err 메소드는 스캔 중 발생한 모든 오류를 반환한다.
단, io.EOF 이면 Err 은 nil 을 반환한다.
Split 함수가 입력을 진행하지 않고 너무 많은 빈 토큰을 반환하면 패닉을 스캔한다. 이때는 스캐너의 일반적인 오류 모드이다.
func (s *Scanner) Split(split SplitFunc)
스캐너의 분할 기능을 설정한다. 기본 분할 기능은 ScanLines 이다.
스캔 시작 후 호출되면 분할 패닉이 발생한다.
func (s *Scanner) Text() string
Scan 호출에 의해 생성된 가장 최근 토큰을 새당 바이트를 포함하는 할당된 문자열로 반환한다.
type SplitFunc func (data [] byte , atEOF bool )
(advance int , token [] byte , err error )
입력을 토큰화 하는데 사용되는 분할 함수이다.
인수는 처리되지 않은 나머지 데이터의 초기 하위 문자열과 독자에게 더 이상 제공할 데이터가 없는지 여부를 반환하는 플래그 atEOF 이다.
반환 값은 입력을 진행할 바이트 수와 사용자에게 반환할 다음 토큰 및 오류이다.
함수가 오류를 반환하면 스캔이 중지되며, 이 경우 일부 입력이 삭제될 수 있다.
그렇지 않으면 스캐너가 입력을 진행하고, 토큰이 nil
이 아니면 스캐너는 토큰을 사용자에게 반환한다.
토큰이 nil
이면 스캐너는 더 많은 데이터를 읽고 스캔을 계속한다.
type Writer struct {
// 필터링되거나 내보내지지 않은 필드 포함
}
io.Writer 객체에 대한 버퍼링을 구현한다.
모든 데이터가 기록된 후에 클라이언트는 모든 데이터가 기본 io.Writer 로 전달되었는지 확인을 위해 Flush 메소드를 호출해야한다.
func NewWriter(w io.Writer) *Writer
버퍼가 기본 크기인 새 작성기를 반환한다.
func NewWriterSize(w io.Writer, size int) *Writer
버퍼에 최소한 지정된 크기가 있는 새 작성기를 반환한다.
인수 io.Writer 가 이미 충분히 큰 Writer 인 경우 기본 Writer 를 반환한다.
func (b *Writer) Abailable() int
버퍼에서 사용되지 않은 바이트 수를 반환한다.
func (b *Writer) Buffered() int
현재 버퍼에 기록된 바이트 수를 반환한다.
func (b *Writer) Flush() error
버퍼링된 데이터를 기본 io.Writer 에 쓴다.
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)
io.ReaderFrom 을 구현한다.
작성기가 ReadFrom 메소드를 지원하고 b
에 아직 버퍼링된 데이터가 없을 경우 버퍼링없이 기본 ReadFrom 을 호출한다.
func (b *Writer) Reset(w io.Writer)
플러시되지 않은 버퍼링된 데이터를 버리고 오류를 지운 후 b
를 재설정하여 w
에 출력을 기록한다.
func (b *Writer) Size() int
기본 버퍼의 크기를 바이트 단위로 반환한다.
func (b *Writer) Write(p []byte) (nn int, err error)
p
의 내용을 버퍼에 쓴다. 쓴 바이트 수를 반환한다.
nn < len(p)
이면 쓰기가 짧은 이유를 설명하는 오류도 반환한다.
func (b *Writer) WriteByte(c byte) error
단일 바이트를 쓴다.
func (b *Writer) WriteRun(r rune) (size int, err error)
단일 유니코드 포인트를 작성하여 쓴 바이트 수와 오류를 반환한다.
func (b *Writer) WriteString(s string) (int, error)
문자열을 쓴다.
쓴 바이트 수를 반환하며 개수가 len(s)
보다 작으면 쓰기가 짧은 이류를 설명하는 오류도 반환한다.
접미사 배열은 메모리 내 접미사 배열을 사용하여 로그 시간으로 하위 문자열 검색을 구현할 수 있다.
예시
// 일부 데이터에 대한 색인 생성
index := suffixarray.New(data)
// 바이트 슬라이스 조회
offset1 := index.Lookup(s, -1) // s 가 발생하는 모든 인덱스 목록
offset2 := index.Lookup(s, 3) // s 가 발생하는 최대 3 개의 인덱스 목록
인덱스는 빠른 하위 문자열 검색을 한다
type Index struct {
// 필터링되거나 내보내지지 않은 필드 포함
}
func New(data []byte) *Index
데이터에 대한 새 색인을 만든다.
인덱스 생성 시간은 N = len(data)
에 대해 O(N)
이다.
func (x *Index) Bytes() []byte
인덱스가 생성된 데이터를 반환한다. 수정해서는 안된다.
func (x *Index) FindAllIndex(r *regexp.Regexp, n int)(result [][]int)
정규식 r
의 겹치지 않는 일치 항목의 정렬 목록을 반환한다.
여기서 일치하는 x.Bytes()
조각을 지정하는 인덱스 쌍이다.
func (x *Index) Lookup(s []byte, n int) (result []int)
인덱싱된 데이터에서 바이트 문자열 s
가 발생하는 최대 n
인덱스의 정렬되지 않은 목록을 반환한다.
func (x *Index) Read(r io.Reader) error
r
에서 x
로 색인을 읽는다. x
는 nil
이 아니어야 한다.
func (x *Index) Write(w io.Writer) error
인덱스 x
를 w
에 쓴다.
실행중인 GO 프로그램에 포함된 파일에 대한 엑세스를 제공한다.
소스 파일은 //go:embed
지시문을 사용하여 컴파일 타임에 패키지 디렉토리 또는 하위 디렉토리에서 읽은 파일 내용으로 문자열, []byte 도는 FS 유형의 변수를 초기화할 수 있다.
다음과 같은 세 가지 방법이 있다.
import _ "embed"
//go:embed hello.txt
var s string
print(s)
import _ "embed"
//go : embed hello.txt
var b [] byte
print (string (b))
import "embed"
//go : embed hello.txt
var f embed.FS
데이터, _ : = f.ReadFile ( "hello.txt")
print (string (data))
변수 선언 위에 //go:embed
지시문으로 파일을 지정한다.
지시문은 단일 변수 선언이 포함된 행 바로 앞에 와야한다.
지시문과 선언 사이에 빈 라인과 주석 만 허용된다.
변수 유형은 문자열 유형, 바이트 유형의 슬라이스 또는 FS 여야 한다.
예시
package server
import "embed"
// 정적 웹 서버 콘텐츠를 소유
//go:embed image/* template/*
//go:embed html/index.html
var content embed.FS
GO 빌드 시스템에서 지시문을 인식하고 선언된 변수가 가진 파일 시스템의 일치하는 파일로 채워지도록 정렬한다.
공백으로 구분된 여러 패턴을 허용하지만 패턴이 많을 때 긴 줄을 피하기 위해 반복할 수도 있다.
패턴은 소스 파일이 포함된 패키지 디렉토리를 기준으로 해석된다.
경로 구분 기호는 슬래시이며 .
가 포함될 수 없다. 또는 ..
과 빈 경로 요소, 슬래시로 시작하거나 끝낼 수 없다.
현 디렉토리의 모든 항목을 일치 시키려면 .
대신 *
을 사용하자.
이름에 공백이 있는 파일 이름은 큰 따옴표 또는 역따옴표 문자열 리터럴로 작성할 수 있다.
패턴이 디렉토리 이름을 지정하면 .
로 시작하는 이름을 가진 파일을 제외하고 해당 디렉토리를 루트로 하는 서브 트리의 모든 파일이 임데드 된다.
또는 _
는 제외한다. 그래서 위 예시는 다음 예시와 거의 같다.
예시
// 정적 웹 서버 콘텐츠
//go:embed image template html/index.html
var content embed.FS
차이점은 image/*
는 image/.tempfile
을 포함하고 image
는 포함하지 않는다는 것이다.
string 또는 []byte 유형의 변수에 대한 //go:embed
행은 단일 패턴만 가질 수 있으며 해당 패턴은 단일 파일과 일치할 수 있다.
문자열 또는 []byte 는 해당 파일의 내용으로 초기화된다.
단일 파일을 포함하려면 문자열 또는 []byte 유형의 변수가 가장 좋다.
FS 유형을 사용하려면 정적 웹 서버 콘텐츠의 디렉토리와 같은 파일 트리를 포함할 수 있다.
FS 는 io/fs 패키지의 FS 인터페이스를 구현하므로 net/http, text/template 및 html/template 를 포함하여 파일 시스템으ㅡㄹ 이해하는 모든 패키지와 함께 사용할 수 있다.
예로 위 예에서 콘텐츠 변수가 주어진다면 다음과 같이 작성할 수 있다.
http.Handle("/static/",
http.StripPrefix("/static/", http.FileServer(http.FS(content))))
template.ParseFS(content, "*.tmpl")
GO 패키지를 분석하는 도구를 지원하기 위해 //go:embed
행에 있는 패턴을 go list
출력에서 사용할 수 있다.
type FS struct {
// 필터링되거나 내보내지지 않은 필드 포함
}
FS 는 읽기 전용 파일 모음이며 일반적으로 //go:embed
지시문으로 초기화된다. 지시문 없이 선언하면 FS 는 빈 파일 시스템이다.
FS 는 읽기 전용 값이기 때문에 여러 고루틴에서 동시에 사용하는 것이 안전하며 서로 FS 유형의 값을 할당하는 것도 안전하다.
FS 는 fs.FS 를 구현하므로 net/http, text/template 및 html/template 을 포함하여 파일 시스템 인터페이스를 이해하는 모든 패키지와 함께 사용할 수 있다.
func (f FS) Open(name string) (fs, File, error)
읽기 위해 명명된 파일을 열고 fs.File 을 반환한다.
func (f FS) ReadDir(name string)([]fs, DirEntry, error)
명명된 전체 디렉터리를 읽고 반환한다.
func (f FS) ReadFile(name string) ([]byte, error)
명명된 파일의 내용을 읽고 반환한다.