登录
首页 >  Golang >  Go问答

如何保护在程序A打开时防止程序B存档/删除文件的Go实现?

来源:stackoverflow

时间:2024-02-09 11:52:48 112浏览 收藏

各位小伙伴们,大家好呀!看看今天我又给各位带来了什么文章?本文标题《如何保护在程序A打开时防止程序B存档/删除文件的Go实现?》,很明显是关于Golang的文章哈哈哈,其中内容主要会涉及到等等,如果能帮到你,觉得很不错的话,欢迎各位多多点评和分享!

问题内容

编程语言:使用最新版本

我正在开发一个程序 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://en.wikipedia.org/wiki/Lsof

好了,本文到此结束,带大家了解了《如何保护在程序A打开时防止程序B存档/删除文件的Go实现?》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>