プログラミング言語 golang golang struct Go 言語のデータ I/O オブジェクトと操作

Go 言語のデータ I/O オブジェクトと操作

 
 
Go 言語では、ほぼすべてのデータ構造がインターフェイスを中心に展開され、インターフェイスは Go 言語のすべてのデータ構造の中核となります。実際の開発プロセスでは、Web アプリケーションの実装であっても、コンソールの入出力であっても、ネットワーク操作であっても、I/O 操作が発生することは避けられません。

 

Go言語標準ライブラリのbufioパッケージでは、データ入出力インタフェースのバッファ機能を実現しています。これらの関数は、インターフェイス io.ReadWriter、io.Reader、および io.Writer にカプセル化されており、それに応じて ReadWriter、Reader、または Writer オブジェクトを作成し、バッファリングを提供しながらいくつかの基本的なテキスト I/O 操作関数を実現します。

ReadWriter オブジェクト

ReadWriter オブジェクトは、データ I/O インターフェイス io.ReadWriter で入力および出力バッファー操作を実行できます。ReadWriter 構造体は次のように定義されます。

type ReadWriter struct {
    *Reader
    *Writer
}

デフォルトでは、Reader ポインターと Writer ポインターのペアが ReadWriter オブジェクトに格納され、データ I/O オブジェクトの読み取りおよび書き込みバッファー機能も提供されます。

NewReadWriter() 関数を使用して ReadWriter オブジェクトを作成できます。この関数の機能は、指定された Reader および Writer に基づいて ReadWriter オブジェクトを作成することです。ReadWriter オブジェクトは、基礎となる io.ReadWriter インターフェイスにデータを書き込むか、データを読み取りますio.ReadWriter インターフェイスから。関数プロトタイプは次のように宣言されます。

func NewReadWriter(r *Reader, w *Writer) *ReadWriter

関数 NewReadWriter() では、パラメータ r は読み取られるソース Reader オブジェクト、パラメータ w は書き込まれる宛先 Writer オブジェクトです。

リーダーオブジェクト

Reader オブジェクトは、データ I/O インターフェイス io.Reader で入力バッファリング操作を実行でき、Reader 構造体は次のように定義されます。

type Reader struct {
    //contains filtered or unexported fields
)

デフォルトでは、Reader オブジェクトには初期値が定義されておらず、入力バッファの最小値は 16 です。制限を超えると、さらに 2 倍のストレージ スペースが作成されます。

Reader オブジェクトを作成する

Reader オブジェクトを作成できる関数は、以下に紹介する NewReader() と NewReaderSize() の 2 つです。

1) NewReader() 関数

NewReader() 関数の機能は、バッファのデフォルトの長さに応じて Reader オブジェクトを作成することです。Reader オブジェクトは、キャッシュのために基礎となる io.Reader インターフェイスから可能な限り多くのデータを読み取ります。関数のプロトタイプは次のとおりです。

func NewReader(rd io.Reader) *Reader

このうち、パラメータ rd は io.Reader インターフェイスであり、Reader オブジェクトはこのインターフェイスからデータを読み取ります。

2) NewReaderSize() 関数

NewReaderSize() 関数の機能は、指定されたバッファ長に従って Reader オブジェクトを作成することです。Reader オブジェクトは、キャッシュのために基礎となる io.Reader インターフェイスから可能な限り多くのデータを読み取ります。関数のプロトタイプは次のとおりです。

func NewReaderSize(rd io.Reader, size int) *Reader

このうち、パラメータ rd は io.Reader インターフェイスであり、パラメータ size は指定されたバッファのバイト長です。

Reader オブジェクトを操作する

Reader オブジェクトを操作するには、Read()、ReadByte()、ReadBytes()、ReadLine()、ReadRune()、ReadSlice()、ReadString()、UnreadByte()、UnreadRune()、Buffered() の 11 のメソッドがあります。 、Peek()、以下それぞれ紹介します。

1) Read()メソッド

Read() メソッドの機能は、データを読み取り、バイト スライス p に保存することです。基礎となる io.Reader は最大 1 回しか呼び出されないため、Read() は実行の最後に読み取られたバイト数を返します。そのため、返される n は len(p) よりも小さくなる可能性があります。バイト ストリームが終了すると、nは 0、err は io.EOF です。メソッドのプロトタイプは次のとおりです。

func (b *Reader) Read(p []byte) (n int, err error)

Read() メソッドでは、パラメータ p は、読み取りデータを格納するために使用されるバイト スライスです。サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data := []byte("IT基礎")
    rd := bytes.NewReader(data)
    r := bufio.NewReader(rd)
    var buf [128]byte
    n, err := r.Read(buf[:])
    fmt.Println(string(buf[:n]), n, err)
} 

操作の結果は次のようになります。

IT基礎 16 <nil>

2) ReadByte() メソッド

ReadByte() メソッドの機能は、バイトを読み取って返し、読み取れるバイトがない場合はエラー メッセージを返すことです。メソッドのプロトタイプは次のとおりです。

func (b *Reader) ReadByte() (c byte,err error)

サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data := []byte("Go入門")
    rd := bytes.NewReader(data)
    r := bufio.NewReader(rd)
    c, err := r.ReadByte()
    fmt.Println(string(c), err)
} 

操作の結果は次のようになります。

G <nil>

3) ReadBytes() メソッド

ReadBytes() メソッドの機能は、最初の区切り文字「delim」に到達するまでデータを読み取り、読み取られたバイトのシーケンス (「delim」を含む) を返すことです。最初の「delim」を読み取る前に ReadBytes でエラーが発生した場合、読み取られたデータとそのエラー (通常は io.EOF) が返されます。返されるエラーが null でないのは、返されたデータが「delim」で終わっていない場合のみです。メソッドのプロトタイプは次のとおりです。

func (b *Reader) ReadBytes(delim byte) (line []byte, err error)

このうち、パラメータ delim は分割バイトを指定するために使用されます。サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data := []byte("IT基礎、Go言語入門チュートリアル")
    rd := bytes.NewReader(data)
    r := bufio.NewReader(rd)
    var delim byte = '、'
    line, err := r.ReadBytes(delim)
    fmt.Println(string(line), err)
} 

操作の結果は次のようになります。

IT基礎、 <nil>

4) ReadLine()メソッド

ReadLine() はデータ行を読み取るための低レベルのメソッドであり、ほとんどの呼び出し元は ReadBytes(‘\n’) または ReadString(‘\n’) を使用する必要があります。 ReadLine は、末尾のキャリッジ リターン文字を除いた行を返します。行が長すぎる (バッファ長を超える) 場合、パラメータ isPrefix が true に設定され、前のデータのみが返され、残りのデータは返されます。後続の呼び出しで返されます。

データの最後の行が返されると、パラメーター isPrefix は false に設定されます。返されたバイト スライスは、次に ReadLine が呼び出されるまでのみ有効です。 ReadLine は空ではないバイト スライスまたはエラーを返します。メソッドのプロトタイプは次のとおりです。

func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)

サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data := []byte("Golangは美しい言語です。\r\n 私はそれが好きです!")
    rd := bytes.NewReader(data)
    r := bufio.NewReader(rd)
    line, prefix, err := r.ReadLine()
    fmt.Println(string(line), prefix, err)
} 

操作の結果は次のようになります。

Golangは美しい言語です。  false <nil>

5) ReadRune()メソッド

ReadRune() メソッドの機能は、UTF-8 でエンコードされた文字を読み取り、その Unicode エンコードとバイト数を返すことです。エンコードが間違っている場合、ReadRune は 1 バイトを読み取るだけで、unicode.ReplacementChar(U+FFFD) と長さ 1 を返します。メソッドのプロトタイプは次のとおりです。

func (b *Reader) ReadRune() (r rune, size int, err error)

サンプルコードは次のとおりです。

 package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data := []byte("IT基礎")
    rd := bytes.NewReader(data)
    r := bufio.NewReader(rd)
    ch, size, err := r.ReadRune()
    fmt.Println(string(ch), size, err)
} 

操作の結果は次のようになります。

IT1 <nil>

6) ReadSlice()メソッド

ReadSlice() メソッドの機能は、データを区切り文字「delim」まで読み取り、読み取ったデータのバイトスライスを返すことです。返されたスライスは、次回データを読み取るときには無効になります。 ReadSlice が「delim」を見つける前にエラーが発生した場合は、読み取られたすべてのデータとそのエラー (通常は io.EOF) が返されます。

バッファがいっぱいのときに「delim」が見つからない場合は、ErrBufferFull エラーを返します。 ReadSlice によって返されたデータは次の I/O 操作で上書きされるため、ほとんどの呼び出し元は ReadBytes または ReadString を使用する必要があります。 ReadSlice は、行が「delim」で終わっていない場合にのみ、null 以外のエラーを返します。メソッドのプロトタイプは次のとおりです。

func (b *Reader) ReadSlice(delim byte) (line []byte, err error)

このうち、パラメータ delim は分割バイトを指定するために使用されます。サンプルコードは次のとおりです。

 package main

 (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data:= []byte("IT基礎、Go言語入門チュートリアル")
    rd:= bytes.NewReader(data)
    r:= bufio.NewReader(rd)
    var delim byte = '、'
    line, err:= r.ReadSlice(delim)
    fmt.Println(string(line), err)
    ine, err = r.ReadSlice(delim)
    fmt.Println(string(line), err)
    ine, err = r.ReadSlice(delim)
    fmt.Println(string(line), err)
} 

操作の結果は次のようになります。

IT基礎, <nil>
Go语言入门チュートリアル EOF
EOF

7) ReadString() メソッド

ReadString() メソッドの機能は、区切り文字「delim」が最初に出現するまでデータを読み取り、「delim」を含む文字列を返すことです。 ReadString は、「delim」を読み取る前にエラーが発生した場合、読み取った文字列とそのエラー (通常は io.EOF) を返します。 ReadString は、返された文字列が「delim」で終わっていない場合にのみ、null 以外のエラーを返します。メソッドのプロトタイプは次のとおりです。

func (b *Reader) ReadString(delim byte) (line string, err error)

このうち、パラメータ delim は分割バイトを指定するために使用されます。サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data := []byte("IT基礎, Go言語入門チュートリアル")
    rd := bytes.NewReader(data)
    r := bufio.NewReader(rd)
    var delim byte = ','
    line、err := r.ReadString(delim)
    fmt.Println(line、err)
} 

操作の結果は次のようになります。

IT基礎, <nil>

8) UnreadByte()メソッド

UnreadByte() メソッドの機能は、読み取られた最後のバイトをキャンセルすることです (つまり、バイトを読み取りバッファーの先頭に戻します)。読み取られた最後の 1 バイトのみを未読にできます。メソッドのプロトタイプは次のとおりです。

func (b *Reader) UnreadByte() error

9) UnreadRune()メソッド

UnreadRune() メソッドの機能は、最後に読み取られた Unicode 文字を元に戻すことです。最後の読み取り操作が ReadRune ではなかった場合、UnreadRune はエラーを返します (UnreadByte は最後の読み取り操作の最後のバイトをキャンセルするため、この点では UnreadByte よりも厳密です)。メソッドのプロトタイプは次のとおりです。

func (b *Reader) UnreadRune() error

10) Buffered() メソッド

Buffered() メソッドの機能は、バッファから読み取ることができるデータのバイト数を返すことです。サンプル コードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data := []byte("Go入門")
    rd := bytes.NewReader(data)
    r := bufio.NewReader(rd)
    var buf [14]byte
    n, err := r.Read(buf[:])
    fmt.Println(string(buf[:n]), n, err)
    rn := r.Buffered()
    fmt.Println(rn)
    n, err = r.Read(buf[:])
    fmt.Println(string(buf[:n]), n, err)
    rn = r.Buffered()
    fmt.Println(rn)
} 

11) Peek() メソッド

Peek() メソッドの機能は、指定されたバイト数のデータを読み取ることであり、読み取られたデータはバッファからクリアされません。次回の読み取り後、今回返されたバイト スライスは無効になります。 Peek が返すバイト数が n バイト未満の場合は、その理由を説明するエラーが返され、n がバッファより大きい場合は、エラーは ErrBufferFull になります。メソッドのプロトタイプは次のとおりです。

func (b *Reader) Peek(n int) ([]byte, error)

Peek() メソッドのパラメータ n は、読み取るバイト数です。サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    data := []byte("Goチュートリアル")
    rd := bytes.NewReader(data)
    r := bufio.NewReader(rd)
    bl, err := r.Peek(8)
    fmt.Println(string(bl), err)
    bl, err = r.Peek(14)
    fmt.Println(string(bl), err)
    bl, err = r.Peek(20)
    fmt.Println(string(bl), err)
} 

 

ライターオブジェクト

Writer オブジェクトは、データ I/O インターフェイス io.Writer で出力バッファリング操作を実行でき、Writer 構造体は次のように定義されます。

type Writer struct {
    //contains filtered or unexported fields
}

デフォルトでは、Writer オブジェクトには初期値が定義されていません。出力バッファリング プロセス中にエラーが発生した場合、データの書き込み操作は直ちに終了し、後続の書き込み操作では書き込み例外エラーが返されます。

Writer オブジェクトを作成する

Writer オブジェクトを作成するには、NewWriter() と NewWriterSize() という 2 つの関数があります。これらについては、以下で紹介します。

1) NewWriter() 関数

NewWriter() 関数の機能は、デフォルトのバッファ長に従って Writer オブジェクトを作成することであり、Writer オブジェクトはキャッシュされたデータを基礎となる io.Writer インターフェイスにバッチで書き込みます。関数のプロトタイプは次のとおりです。

func NewWriter(wr io.Writer) *Writer

このうち、パラメータ wr は io.Writer インターフェイスであり、Writer オブジェクトはこのインターフェイスにデータを書き込みます。

2) NewWriterSize() 関数

NewWriterSize() 関数の機能は、指定されたバッファ長に従って Writer オブジェクトを作成することであり、Writer オブジェクトはキャッシュされたデータを基礎となる io.Writer インターフェイスにバッチで書き込みます。関数のプロトタイプは次のとおりです。

func NewWriterSize(wr io.Writer, size int) *Writer

このうち、パラメータ wr は io.Writer インターフェイス、パラメータ size は指定されたバッファのバイト長です。

Writer オブジェクトを操作する

Writer オブジェクトを操作するには、Available()、Buffered()、Flush()、Write()、WriteByte()、WriteRune()、および WriteString() メソッドの 7 つのメソッドがあり、これらについては以下で説明します。

1)Available()メソッド

Available() メソッドの機能は、バッファ内の未使用のバイト数を返すことです。このメソッドのプロトタイプは次のとおりです。

func (b *Writer) Available() int

サンプルコードは次のとおりです。

 package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    wr := bytes.NewBuffer(nil)
    w := bufio.NewWriter(wr)
    p := []byte("IT基礎")
    fmt.Println("書き込む前の未使用のバッファーサイズは:", w.Available())
    w.Write(p)
    fmt.Printf("%qを書き込んだ後、未使用のバッファーサイズは:%d\n", string(p), w.Available())
} 

2) Buffered() メソッド

Buffered() メソッドの機能は、現在のバッファに書き込まれたバイト数を返すことです。このメソッドのプロトタイプは次のとおりです。

func (b *Writer) Buffered() int

サンプルコードは次のとおりです。

 パッケージmain

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    wr := bytes.NewBuffer(nil)
    w := bufio.NewWriter(wr)
    p := []byte("IT基礎")
    fmt.Println("書き込み前の未使用緩衝領域は:", w.Buffered())
    w.Write(p)
    fmt.Printf("%qを書き込んだ後、未使用緩衝領域は:%d\n", string(p), w.Buffered())
    w.Flush()
    fmt.Println("Flushメソッドを実行後、書き込まれたバイト数は:", w.Buffered())
} 

3) Flush() メソッド

Flush() メソッドの機能は、バッファ内のデータを基礎となる io.Writer に書き込み、エラー メッセージを返すことです。書き込みが成功した場合、error は nil を返し、それ以外の場合、error はエラー理由を返します。メソッドのプロトタイプは次のとおりです。

func (b *Writer) Flush() error

サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    wr := bytes.NewBuffer(nil)
    w := bufio.NewWriter(wr)
    p := []byte("IT基礎")
    w.Write(p)
    fmt.Printf("テスト テスト テスト %q\n", string(wr.Bytes()))
    w.Flush()
    fmt.Printf("テスト テスト テスト %q\n", string(wr.Bytes()))
} 

 

4) Write()メソッド

Write() メソッドの機能は、バイト スライス p をバッファに書き込み、書き込まれたバイト数 nn を返すことです。 nn が len(p) より小さい場合、エラー理由も返されます。メソッドのプロトタイプは次のとおりです。

func (b *Writer) Write(p []byte) (nn int, err error)

ここで、パラメータ p は書き込むバイト スライスです。サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    wr := bytes.NewBuffer(nil) // バイト配列の新しいバッファを作成
    w := bufio.NewWriter(wr) // バッファのライターを作成
    p := []byte("IT基礎") // バイトスライスを作成
    n, err := w.Write(p) // ライターにスライスを書き込む
    w.Flush() // バッファをフラッシュし、すべての書き込みをライターに送信する
    fmt.Println(string(wr.Bytes()), n, err) // 書き込んだバッファのデータを文字列に変換して出力する
} 

操作の結果は次のようになります。

IT基礎 16 <nil>

5) WriteByte()メソッド

WriteByte() メソッドの機能はバイトを書き込むことです。書き込みが成功するとエラーは nil を返し、それ以外の場合はエラーはエラー理由を返します。メソッドのプロトタイプは次のとおりです。

func (b *Writer) WriteByte(c byte) error

このうちパラメータ c は、ASCII 文字などの書き込むバイトデータです。サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

funcメイン() {
    wr:=bytes.NewBuffer(nil)
    w:=bufio.NewWriter(wr)
    var c byte = 'G'
    err:= w.WriteByte(c)
    w.Flush()
    fmt.Println(string(wr.Bytes()), err)
} 

操作の結果は次のようになります。

G <nil>

6) WriteRune() メソッド

WriteRune() メソッドの機能は、Unicode 文字を UTF-8 エンコーディングで書き込み、書き込まれたバイト数とエラー メッセージを返すことです。メソッドのプロトタイプは次のとおりです。

func (b *Writer) WriteRune(r rune) (size int,err error)

ここで、パラメータ r は書き込む Unicode 文字です。サンプルコードは次のとおりです。

 package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    // Bufferの作成
    wr := bytes.NewBuffer(nil)
    w := bufio.NewWriter(wr)
    //文字'R'を書き込み
    var r rune = 'G'
    size, err := w.WriteRune(r)
    // Flushで書き込みを反映
    w.Flush()
    // 書き込んだ文字を表示
    fmt.Println(string(wr.Bytes()), size, err)
} 

この例のテスト結果は次のとおりです。

G 1 <nil>

7) WriteString() メソッド

WriteString() メソッドの機能は、文字列を書き込み、書き込まれたバイト数とエラー メッセージを返すことです。返されたバイト数が len(s) 未満の場合は、その理由を説明するエラーも返されます。メソッドのプロトタイプは次のとおりです。

func (b *Writer) WriteString(s string) (int, error)

このうちパラメータ s は書き込む文字列です。サンプルコードは次のとおりです。

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    wr := bytes.NewBuffer(nil)
    w := bufio.NewWriter(wr)
    s := "IT基礎"
    n, err := w.WriteString(s)
    w.Flush()
    fmt.Println(string(wr.Bytes()), n, err)
} 

操作の結果は次のようになります。

IT基礎 16 <nil>

 

「 Go 言語のデータ I/O オブジェクトと操作」についてわかりやすく解説!絶対に観るべきベスト2動画

【たった1時間で学べる】Go言語のプログラミング初心者向けの超入門講座【文字書き起こし、ソースコードも完全無料!】
【今週公開された最新AIのすべて】ChatGPTにwebブラウジング機能とプラグイン実装/全自動作詞・作曲AI登場/手軽に高性能AIボイチェンアプリ/AIマッチングアプリ爆誕