首頁 > 後端開發 > Golang > 主體

Go中如何防止程式B歸檔/刪除程式A目前開啟的檔案?

王林
發布: 2024-02-10 23:33:07
轉載
720 人瀏覽過

Go中如何防止程式B歸檔/刪除程式A目前開啟的檔案?

Go語言是一門強大的程式語言,但在處理檔案操作時可能會遇到一些問題。特別是當程式A開啟一個檔案時,程式B可能會嘗試對該檔案進行歸檔或刪除,這可能導致程式A出現錯誤。 php小編西瓜在這裡給出一些方法,幫助您在Go語言中防止程式B對程式A目前開啟的檔案進行操作,確保程式的穩定運作。以下是一些解決方案:

問題內容

程式語言:使用最新版本

我正在開發一個程式 A,它需要將日誌檔案歸檔到一個目錄中,不包括由程式 B 打開的日誌文件,該程式使用它來進行日誌記錄。開啟的檔案將在特定持續時間(例如 24 小時)後關閉,然後可用於存檔。顯然,兩個程式都是獨立運作的。

當前的實作不會檢查程式 B 中的文件是否打開,因為我最近發現它正在歸檔打開的日誌文件,我認為它不會這樣做;基本上,它將文件複製到存檔並刪除它。

在嘗試歸檔檔案之前檢查檔案目前是否已被另一個 Go 程式開啟的可靠方法是什麼?

我已經編寫了歸檔器,但我不會將其發佈在這裡,因為沒有與問題無關的程式碼,因此我只添加執行歸檔和刪除的程式碼。

我嘗試過使用 Open 和 OpenFile 函數,但沒有成功。

func zipFile(filename string) error {
    file, err := os.Open(filename)

    if err != nil {
        return err
    }

    defer func(file *os.File) {
        err = file.Close()

        if err != nil {
            fmt.Println(err)
        }
    }(file)

    fileInfo, err := file.Stat()

    if err != nil {
        return err
    }

    archiveFile, err := os.Create(fmt.Sprintf("%s.zip", filename))

    if err != nil {
        return err
    }

    defer func(archiveFile *os.File) {
        err = archiveFile.Close()

        if err != nil {
            fmt.Println(err)
        }
    }(archiveFile)

    zipWriter := zip.NewWriter(archiveFile)

    if err != nil {
        return err
    }

    defer func(zipWriter *zip.Writer) {
        err = zipWriter.Close()

        if err != nil {
            fmt.Println(err)
        }
    }(zipWriter)

    writer, err := zipWriter.Create(fileInfo.Name())

    if err != nil {
        return err
    }

    _, err = io.Copy(writer, file)

    if err != nil {
        return err
    }

    err = os.Remove(filename)

    if err != nil {
        return err
    }

    fmt.Println(fmt.Sprintf("file %s was zipped", fileInfo.Name()))

    return nil
}
登入後複製

解決方法

無論進程如何,了解某個檔案是否被另一個進程開啟的問題都非常依賴底層作業系統。因此,沒有通用的跨平台方法來回答這個問題。對於 *NIX 系統(Unix、Linux、macOS),回答問題的最佳方法是使用核心 util lsof(「列出開啟的檔案」)。

在 macOS 上,看起來像這樣:

package main

import (
    "fmt"
    "os/exec"
    "strings"
)

func main() {
    out, _ := exec.Command("lsof").Output()
    for _, line := range strings.Split(string(out), "\n") {
        // Skip anything that's not a regular file
        if !strings.Contains(line, "REG") { 
            continue
        }

        fields := strings.Fields(line)

        // The macOS lsof command has the filename in the ninth field
        fmt.Println(fields[8])
    }
}
登入後複製

或者,您可以找到一個對此進行抽象的庫,例如:https://github.com/車輪綜合體/lsof

#有關 lsof 的更多資訊:https://www.php.cn/link/fa2246fa0fdf0d3e270c86767b77ba1b

以上是Go中如何防止程式B歸檔/刪除程式A目前開啟的檔案?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板