web-dev-qa-db-ja.com

ファイルからの読み取り中にEOFを見つける方法

Goでファイルを読み取るために次のコードを使用しています。

spoon , err := ioutil.ReadFile(os.Args[1])
if err!=nil {
        panic ("File reading error")
}

次に、選択したすべてのバイトをチェックして、その文字を確認します。例えば:

spoon[i]==' ' //for checking space

同様に、ファイル全体を読み取ります(他の読み取り方法もあると思います)が、この方法をそのまま使用すると、ファイルのEOFに達したことを確認でき、読み取りを停止する必要がありますさらに?

spoonの長さを見つけてループを開始するように提案しないでください。 EOFを見つける確実な方法が欲しい。

18
Worlock

使用する io.EOFファイルの終わりをテストします。たとえば、ファイル内のスペースを数えるには:

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    if len(os.Args) <= 1 {
        fmt.Println("Missing file name argument")
        return
    }
    f, err := os.Open(os.Args[1])
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()
    data := make([]byte, 100)
    spaces := 0
    for {
        data = data[:cap(data)]
        n, err := f.Read(data)
        if err != nil {
            if err == io.EOF {
                break
            }
            fmt.Println(err)
            return
        }
        data = data[:n]
        for _, b := range data {
            if b == ' ' {
                spaces++
            }
        }
    }
    fmt.Println(spaces)
}
19
peterSO

ioutil.ReadFile()は、ファイルの内容全体をバイトスライスに読み取ります。 EOFを気にする必要はありません。 EOFは、一度に1つのチャンクでファイルを読み取るときに必要な構成です。一度に1つのチャンクを読み取る場合は、どのチャンクがファイルの最後に達したかを知る必要があります。 。

ioutil.ReadFile()によって返されるバイトスライスの長さは、必要なすべてです。

data := ioutil.ReadFile(os.Args[1])

// Do we need to know the data size?
slice_size := len(data)

// Do we need to look at each byte?
for _,byte := range data {
    // do something with each byte
}
7
Daniel

ioutil.ReadFile()を使用する場合、設計上、io.EOFは表示されません。ReadFileはEOFに到達するまでファイル全体を読み取るためです。したがって、返されるスライスisファイル全体。ドキュメントから:

ReadFileは、filenameで指定されたファイルを読み取り、その内容を返します。呼び出しが成功すると、err == EOFではなく、err == nilが返されます。 ReadFileはファイル全体を読み取るため、ReadのEOF=をレポート対象のエラーとして扱いません。

あなたの質問から、ファイルを読み取る他の方法があることを知っていることを明示的に述べ、それらの方法のいくつかはio.EOFのエラーをテストする必要がありますが、ReadFileはテストしません。

次に、所有しているスライスを使用して、for ... range構文を使用してファイルを読み取ることができます。これは、ファイル全体を読み取るためのsure方法です(ここでも、ReadFileが処理します)。または、0からlen(spoon)まで繰り返す-1も機能しますが、範囲はより慣用的であり、基本的に同じです。

つまり、スライスの最後に到達すると、ファイルの最後に到達します(ReadFileがエラーを返さなかった場合)。

3
mna

スライスには、ファイルの終わりという概念はありません。 ioutil.ReadFileによって返されるスライスには特定の長さがあり、これは読み込まれたファイルのサイズを反映しています。一般的なイディオムですが、この場合に使用できるのは1つだけですが、スライスを範囲指定して、元々ファイルに存在していたすべてのバイトを効果的に「消費」します。

for i, b := range spoon {
        // At index 'i' is byte 'b'
        // At file's offset 'i', 'b' was read
        ... do something useful here
}
2
zzzz