Rumah >pembangunan bahagian belakang >Golang >Bincangkan bagaimana Golang melaksanakan fungsi ekor

Bincangkan bagaimana Golang melaksanakan fungsi ekor

PHPz
PHPzasal
2023-04-05 09:09:211275semak imbas

Golang ialah bahasa pengaturcaraan moden yang semakin popular dan disokong oleh orang ramai. Dengan ciri yang cekap dan stabil, ia bukan sahaja dapat memenuhi keperluan pembangun untuk prestasi tinggi dan penggunaan sumber yang rendah, tetapi juga dapat melaksanakan pelbagai fungsi.

Dalam artikel ini, kami akan meneroka cara Golang melaksanakan fungsi ekor, yang memantau perubahan dalam fail dan mengeluarkan beberapa baris maklumat terakhir dalam fail.

Idea Pelaksanaan

Sebelum kita mula melaksanakan fungsi ekor, kita perlu terlebih dahulu memahami idea asas pelaksanaannya. Secara umum, kita perlu melaksanakan fungsi berikut:

  1. Buka fail dengan laluan yang diberikan dan baca keseluruhan kandungan fail.
  2. Dapatkan saiz fail dan simpan kedudukan penunjuk fail.
  3. Gunakan goroutine bahasa Go untuk memantau perubahan fail Jika fail berubah, keluarkan dan kemas kini beberapa baris maklumat terakhir.
  4. Semak perubahan saiz fail mengikut turutan sehingga fail ditutup atau benang dihentikan.

Melaksanakan penghuraian

Mula-mula, kita perlu memperkenalkan pakej os untuk membaca dan menutup fail. Kita juga perlu menentukan jenis struktur untuk mewakili fungsi ekor.

package main

import (
    "fmt"
    "os"
)

type Tail struct {
    File   *os.File // 文件指针
    Size   int64    // 文件大小
    Cursor int64    // 文件指针所在位置
    Rows   int      // 输出行数
}

Kami menentukan jenis struktur Ekor, di mana medan Fail ialah penuding fail, medan Saiz ialah saiz fail, medan Kursor mewakili kedudukan semasa penuding fail dan medan Baris mewakili bilangan baris keluaran.

Seterusnya, kita perlu melaksanakan fungsi pembukaan fail. Di Golang, membaca kandungan fail boleh dilaksanakan melalui pakej os. Selepas kami membuka fail, kami boleh mendapatkan maklumat fail melalui fungsi os.Stat(), termasuk saiz fail, kedudukan penunjuk fail, dsb. Kita juga perlu ingat untuk meletakkan penunjuk fail ke hujung fail.

func (t *Tail) OpenFile(path string, rows int) error {
    var err error

    // 打开文件
    t.File, err = os.Open(path)
    if err != nil {
        fmt.Printf("open file %s err: %s\n", path, err.Error())
        return err
    }

    // 获取文件信息
    fi, err := t.File.Stat()
    if err != nil {
        fmt.Printf("get file info err:%s", err.Error())
        return err
    }

    // 获取文件大小
    t.Size = fi.Size()

    // 将文件指针定位到文件末尾
    _, err = t.File.Seek(0, os.SEEK_END)
    if err != nil {
        fmt.Printf("move file pointer failed. err:%s\n", err.Error())
        return err
    }

    // 设置输出行数
    t.Rows = rows
    return nil
}

Dalam kod, kami mula-mula membuka fail melalui fungsi os.Open() dan mendapatkan maklumat fail melalui fungsi os.Stat(). Seterusnya, kami menggunakan fungsi os.Seek() untuk menghalakan penuding fail ke hujung fail untuk memastikan program membaca maklumat fail terkini.

Mengikut bilangan baris keluaran input oleh pengguna, kami merekodkan maklumat nombor talian. Perlu diingatkan di sini bahawa kita perlu membahagikan bilangan baris dengan 2, kerana satu baris beberapa fail mungkin terdiri daripada berbilang baris, dan pelaksanaan khusus diserahkan kepada pembaca untuk memikirkannya.

Seterusnya, kami melaksanakan pemantauan perubahan output, dilaksanakan dalam goroutine.

func (t *Tail) Follow() {
    defer t.File.Close()

    // 开始监视文件变化
    for {
        fi, err := t.File.Stat()
        if err != nil {
            fmt.Printf("get file info error: %s\n", err.Error())
            return
        }

        // 如果指针超过文件大小,将指针移到文件末尾
        if t.Cursor > fi.Size() {
            _, err = t.File.Seek(0, os.SEEK_END)
            if err != nil {
                fmt.Printf("move file pointer failed. err:%s\n", err.Error())
                return
            }
            t.Cursor = fi.Size()
        }

        // 读取差异部分的内容,并输出
        if fi.Size() > t.Cursor {
            data := make([]byte, fi.Size()-t.Cursor)
            _, err = t.File.ReadAt(data, t.Cursor)
            if err != nil {
                fmt.Printf("read file failed. err:%s\n", err.Error())
                return
            }

            lines := strings.Split(string(data), "\n")
            for i := len(lines) - t.Rows/2; i < len(lines); i++ {
                fmt.Println(lines[i])
            }
            t.Cursor += int64(len(data))

            fmt.Printf("Cursor:%d\n", t.Cursor)
        }

        time.Sleep(1 * time.Second)
    }
}

Dalam goroutine, kami memperoleh maklumat fail melalui fungsi os.File.Stat() dan menyemak sama ada saiz fail telah berubah. Jika saiz fail berubah, kami membaca kandungan bahagian perbezaan dan mengeluarkannya, dan mengemas kini kedudukan penunjuk fail.

Kami membaca kandungan fail dalam baris dan hanya mengeluarkan beberapa baris terakhir Ini untuk mengelakkan masalah baris baru melebihi julat output.

Malah, memulakan goroutine boleh memantau perubahan fail, dan perubahan dalam saiz fail bermakna kandungan fail telah berubah Pada masa ini, kita boleh menggunakan fungsi os.File.ReadAt() untuk membaca perbezaan kandungan dan kemudian mengeluarkannya.

Akhir sekali, kita perlu melaksanakan pencetakan log ralat.

func main() {
    // 构造 Tail 结构体
    t := &Tail{}

    // 打开文件
    err := t.OpenFile("test.log", 20)
    if err != nil {
        return
    }

    // 监听文件变化
    fmt.Println("start following...")
    t.Follow()

    fmt.Println("tail finish.")
}

Dalam fungsi main(), kami mula-mula membuka fail melalui fungsi OpenFile() dan kemudian memantau perubahan fail melalui fungsi Follow() untuk melaksanakan fungsi ekor. Di sini kami memantau perubahan dalam fail dan terus mengeluarkan beberapa baris maklumat terakhir dalam fail sehingga fail ditutup atau program berhenti.

Kesimpulan

Di atas ialah cara Golang melaksanakan fungsi ekor. Ia mudah untuk dilaksanakan dan praktikal pada masa yang sama. Dalam pembangunan sebenar, pengoptimuman yang sepadan boleh dijalankan mengikut keperluan khusus, seperti membaca lebih banyak baris, mengeluarkan ke fail log tertentu, dsb. Pelaksanaan ini boleh membantu pembangun memantau perubahan fail dengan lebih baik dan memenuhi keperluan pembangunan dengan lebih baik.

Atas ialah kandungan terperinci Bincangkan bagaimana Golang melaksanakan fungsi ekor. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn