30

私はGoにまったく慣れておらず、バイナリファイルをバイト単位または一度に数バイトずつ読み取ろうとしています。ドキュメントはあまり役に立ちませんし、チュートリアルや簡単な例を見つけることができません(ちなみに、Googleはどうやって彼らの言語にそのようなグーグルできない名前を付けることができますか?)。基本的に、ファイルを開いてから、いくつかのバイトをバッファに読み込むにはどうすればよいですか?なにか提案を?

4

5 に答える 5

27

ファイルを操作するためのosパッケージはあなたの友達です:

f, err := os.Open("myfile")
if err != nil {
   panic(err)
}
defer f.Close()

ファイルを開く方法の詳細については、os.OpenFile()代わりに(doc)を参照してください。

ファイルを読み取るには、多くの方法があります。os.Fileによって返される型os.Open(上記の例では)は、インターフェイスをf実装し(適切な署名を持つメソッドを持っています)、バッファー(a )内のデータを直接読み取るために使用できます。または、バッファー付きリーダーでラップすることもできます。 (タイプ)。io.ReaderRead()[]bytebufio.Reader

特にバイナリデータの場合、encoding/binaryパッケージは、バイトのシーケンスをデータの型指定された構造に読み込むのに役立ちます。ここのGoドキュメントで例を見ることができます。このbinary.Read()関数は、関数を使用して読み取られたファイルで使用できます。os.Open()前述したように、この関数はio.Readerです。

また、使いやすいio/ioutilパッケージもあります。これを使用すると、ファイル全体を1バイトスライスで一度に読み取ることができます(これはファイル名を使用するため、自分でファイルを開いたり閉じたりする必要はioutil.ReadFile()ありません)。ioutil.ReadAll()aio.Readerと、ファイル全体を含むバイトのスライスを返します。これがioutilのドキュメントです。

最後に、他の人が述べたように、「golang」を使用してGo言語についてグーグルで検索すると、必要なものがすべて見つかるはずです。golang -nutsメーリングリストは、回答を探すのにも最適な場所です(投稿する前に、必ず最初に検索してください。すでに多くの回答があります)。サードパーティのパッケージを探すには、godoc.orgのWebサイトを確認してください。

HTH

于 2013-01-25T02:55:31.947 に答える
13

これは私がバイナリファイル全体をメモリに読み込むために使用するものです

func RetrieveROM(filename string) ([]byte, error) {
    file, err := os.Open(filename)

    if err != nil {
        return nil, err
    }
    defer file.Close()

    stats, statsErr := file.Stat()
    if statsErr != nil {
        return nil, statsErr
    }

    var size int64 = stats.Size()
    bytes := make([]byte, size)

    bufr := bufio.NewReader(file)
    _,err = bufr.Read(bytes)

    return bytes, err
}
于 2013-01-28T21:43:26.780 に答える
10

たとえば、ファイルのゼロバイト数をカウントするには、次のようにします。

package main

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

func main() {
    f, err := os.Open("filename")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()
    data := make([]byte, 4096)
    zeroes := 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 == 0 {
                zeroes++
            }
        }
    }
    fmt.Println("zeroes:", zeroes)
}
于 2013-01-25T07:55:31.657 に答える
3

Cのようにプリミティブ型を(char *)に気まぐれにキャストすることはできないため、バイナリデータのあらゆる種類の(逆)シリアル化には、encoding/binaryパッケージを使用します。 http://golang.org/pkg/encoding/binary。そこの例を改善することはできません。

于 2013-03-06T17:54:24.830 に答える
0

Readメソッドを使用した例を次に示します。

package main

import (
   "io"
   "os"
)

func main() {
   f, e := os.Open("a.go")
   if e != nil {
      panic(e)
   }
   defer f.Close()
   for {
      b := make([]byte, 10)
      _, e = f.Read(b)
      if e == io.EOF {
         break
      } else if e != nil {
         panic(e)
      }
      // do something here
   }
}

https://golang.org/pkg/os#File.Read

于 2021-04-09T04:03:09.887 に答える