2019年12月29日日曜日

golang でファイルの最後の一行を取得する方法

概要

タイトルの通りです
もう少し良い方法はないだろうか

環境

  • macOS 10.15.2
  • golang 1.12.9

読み込むファイル

  • vim test.txt
aaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbb
ccccccccccccccccccc
ddddddddddddddddddd

サンプルコード1: bufio.NewScanner

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    fmt.Println(lastLine())
}

func lastLine() string {
    line := ""
    f, _ := os.Open("./test.txt")
    if err != nil {
        fmt.Println(err)
        return line
    }
    defer f.Close()
    scanner := bufio.NewScanner(f)
    for scanner.Scan() {
        line = scanner.Text()
    }
    return line
}

サンプルコード2: file.Seek

package main

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

func main() {
    fmt.Print(lastLine())
}

func lastLine() string {
    line := ""
    file, err := os.Open("./test.txt")
    if err != nil {
        fmt.Println(err)
        return line
    }
    defer file.Close()
    // 1 行が 19 バイト以上であればさらに大きくする
    byteSize := int64(19)
    // カーソルを最後の行にする
    file.Seek(-1*(byteSize+1), 2)
    b := make([]byte, (byteSize + 1))
    for {
        _, err := file.Read(b)
        if err != nil {
            if err != io.EOF {
                fmt.Println(err)
                return line
            }
            break
        }
        line = string(b)
    }
    return line
}

最後に

個人的には 1 が簡単なので良いのですがファイルのサイズが大きくなると大変なことなります
2 は 1 行ごとにバイトサイズが異なる場合だと考えることが増えます

参考サイト

0 件のコメント:

コメントを投稿