首页 > 后端开发 > Golang > 正文

Go中如何防止程序B归档/删除程序A当前打开的文件?

王林
发布: 2024-02-10 23:33:07
转载
667 人浏览过

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 的更多信息://m.sbmmt.com/link/fa2246fa0fdf0d3e270c86767b77ba1b

以上是Go中如何防止程序B归档/删除程序A当前打开的文件?的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
来源:stackoverflow.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!